/**
* <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>
* BPS Bildungsportal Sachsen GmbH, http://www.bps-system.de
* <p>
*/
package de.bps.course.nodes.den;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.velocity.VelocityContext;
import org.olat.basesecurity.BaseSecurity;
import org.olat.basesecurity.BaseSecurityManager;
import org.olat.basesecurity.BaseSecurityModule;
import org.olat.commons.calendar.CalendarManager;
import org.olat.commons.calendar.model.Kalendar;
import org.olat.commons.calendar.model.KalendarEvent;
import org.olat.commons.calendar.model.KalendarEventLink;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.EscapeMode;
import org.olat.core.gui.components.table.BooleanColumnDescriptor;
import org.olat.core.gui.components.table.DefaultColumnDescriptor;
import org.olat.core.gui.components.table.TableController;
import org.olat.core.gui.components.table.TableGuiConfiguration;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.DefaultController;
import org.olat.core.gui.control.WindowControl;
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.core.id.context.BusinessControlFactory;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.util.CodeHelper;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.coordinate.SyncerExecutor;
import org.olat.core.util.mail.ContactList;
import org.olat.core.util.mail.ContactMessage;
import org.olat.core.util.mail.MailTemplate;
import org.olat.core.util.resource.OresHelper;
import org.olat.course.CourseFactory;
import org.olat.course.ICourse;
import org.olat.course.nodes.CourseNodeFactory;
import org.olat.modules.co.ContactFormController;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryManager;
import de.bps.course.nodes.DENCourseNode;
/**
* Manager for date enrollments, provides methods for the enrollment procedure and persisting
* @author skoeber
*/
public class DENManager {
private final static DENManager denManager = new DENManager();
private DENManager() {
//
}
/**
* This method returns a reference of the static date enrollment manager (singleton pattern)
* @return instance of DENManager
*/
public static DENManager getInstance() {
return denManager;
}
/**
* Enrolls an user into a specific calendar event
* @param identity
* @param event
* @param course
* @param courseNode
* @return status
*/
public DENStatus doEnroll(final Identity identity, final KalendarEvent event, final OLATResourceable ores, final DENCourseNode courseNode) {
return doEnroll(identity, event, ores, courseNode, false);
}
/**
* Enrolls an user into a specific calendar event
* @param identity
* @param event
* @param course
* @param courseNode
* @param allowOverfill
* @return status
*/
public DENStatus doEnroll(final Identity identity, final KalendarEvent event, final OLATResourceable ores, final DENCourseNode courseNode,
final boolean allowOverfill) {
final DENStatus status = new DENStatus();
ICourse course = CourseFactory.loadCourse(ores);
CalendarManager calManager = CoreSpringFactory.getImpl(CalendarManager.class);
final Kalendar cal = calManager.getCourseCalendar(course).getKalendar();
OLATResourceable calRes = calManager.getOresHelperFor(cal);
// reload calendar events
final List<KalendarEvent> denEvents = getDENEvents(ores.getResourceableId(), courseNode.getIdent());
CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(calRes, new SyncerExecutor() {
public void execute() {
boolean error = false;
// try to find choosen calendar event in the reloaded event list
KalendarEvent reloadEvent = event;
for (Iterator<KalendarEvent> iterator = denEvents.iterator(); iterator.hasNext();) {
KalendarEvent kalendarEvent = iterator.next();
if(event.getID().equals(kalendarEvent.getID())) {
reloadEvent = kalendarEvent;
break;
} else if (!iterator.hasNext()) {
// cannot find reloaded calendar event
status.setEnrolled(false);
status.setErrorMessage(DENStatus.ERROR_GENERAL);
error = true;
}
}
Collection<KalendarEvent> collEvents = cal.getEvents();
// check if date is already full
if (!error && !allowOverfill && isDateFull(reloadEvent)) {
status.setEnrolled(false);
status.setErrorMessage(DENStatus.ERROR_FULL);
error = true;
}
// check if identity is already enrolled
if (!error && isAlreadyEnrolled(identity, collEvents, courseNode)) {
status.setEnrolled(false);
status.setErrorMessage(DENStatus.ERROR_ALREADY_ENROLLED);
error = true;
}
// enroll in event
if (!error) {
if (reloadEvent.getParticipants() != null && reloadEvent.getParticipants().length > 0) {
int currLength = reloadEvent.getParticipants().length;
String[] partsNew = new String[currLength + 1]; // one to add
String[] partsOld = reloadEvent.getParticipants();
for (int i = 0; i < partsOld.length; i++) {
partsNew[i] = partsOld[i];
}
partsNew[partsNew.length - 1] = identity.getName();
reloadEvent.setParticipants(partsNew);
} else {
String[] partsNew = new String[] { identity.getName() };
reloadEvent.setParticipants(partsNew);
}
// save calendar event
boolean successfullyDone = calManager.updateEventAlreadyInSync(cal, reloadEvent);
if (!successfullyDone) {
status.setEnrolled(false);
status.setErrorMessage(DENStatus.ERROR_PERSISTING);
}
status.setEnrolled(true);
}
}
});
// success
return status;
}
/**
* Deletes the already enrolled user from the date
* @param identity
* @param event
* @param course
* @param userCourseEnv
* @return status
*/
public DENStatus cancelEnroll(Identity identity, KalendarEvent event, OLATResourceable ores) {
DENStatus status = new DENStatus();
ICourse course = CourseFactory.loadCourse(ores);
CalendarManager calManager = CoreSpringFactory.getImpl(CalendarManager.class);
Kalendar cal = calManager.getCourseCalendar(course).getKalendar();
//check if identity is enrolled
if( !isEnrolledInDate(identity, event) ) {
status.setCancelled(false);
status.setErrorMessage(DENStatus.ERROR_NOT_ENROLLED);
}
//cancel enroll in calendar entry
if(event.getParticipants() != null) {
int currLength = event.getParticipants().length;
if (currLength > 0) {
//more than one are enrolled
List<String> partsNew = new ArrayList<>(currLength); //one to delete
String[] partsOld = event.getParticipants();
String identityName = identity.getName();
for (String partOld:partsOld) {
if (!partOld.equals(identityName)) {
partsNew.add(partOld);
}
}
event.setParticipants(partsNew.toArray(new String[partsNew.size()]));
}
//save calendar event
boolean successfullyDone = calManager.updateEventFrom(cal, event);
if (!successfullyDone) {
status.setCancelled(false);
status.setErrorMessage(DENStatus.ERROR_PERSISTING);
return status;
}
} else {
//no one to cancel
status.setCancelled(false);
status.setErrorMessage(DENStatus.ERROR_GENERAL);
return status;
}
status.setCancelled(true);
//delete date from the users calendar
Kalendar userCal = calManager.getPersonalCalendar(identity).getKalendar();
Collection<KalendarEvent> userEvents = userCal.getEvents();
String sourceNodeId = event.getSourceNodeId();
for( KalendarEvent userEvent : userEvents) {
String eventSourceNodeId = userEvent.getSourceNodeId();
if(eventSourceNodeId != null && eventSourceNodeId.equals(sourceNodeId)) {
calManager.removeEventFrom(userCal, userEvent);
break;
}
}
//success
return status;
}
/**
* Persists settings of the date enrollment
* @param lstEvents
* @param course
* @param denNode
*/
public void persistDENSettings(List<KalendarEvent> lstEvents, OLATResourceable ores, DENCourseNode denNode) {
ICourse course = CourseFactory.loadCourse(ores);
CalendarManager calManager = CoreSpringFactory.getImpl(CalendarManager.class);
Kalendar cal = calManager.getCourseCalendar(course).getKalendar();
String sourceNode = denNode.getIdent();
//remove deleted events
Collection<KalendarEvent> allEvents = new ArrayList<KalendarEvent>(cal.getEvents());
for( KalendarEvent event : allEvents) {
if(event.getSourceNodeId() != null) {
if ( event.getSourceNodeId().equals(sourceNode) && !lstEvents.contains(event) ) {
removeDateInUserCalendar(event);
calManager.removeEventFrom(cal, event);
}
}
}
for( KalendarEvent newEvent : lstEvents ) {
createKalendarEventLinks(course, denNode, newEvent);
KalendarEvent oldEvent = cal.getEvent(newEvent.getID(), newEvent.getRecurrenceID());
//new event?
if (oldEvent != null) {
//event is already in the calendar so first remove it
calManager.removeEventFrom(cal, oldEvent);
}
//now add the event to the course calendar
calManager.addEventTo(cal, newEvent);
//update event in user calendars
addDateInUserCalendar(newEvent);
}
}
/**
* Checks if person is enrolled in specific calendar entry
* @param identity
* @param event
* @return true if person is enrolled, otherwise false
*/
protected boolean isEnrolledInDate(Identity identity, KalendarEvent event) {
if(event.getParticipants() == null)
return false;
return isSubstringInStringArray(identity.getName(), event.getParticipants());
}
/**
* Checks if person is already enrolled in any calendar entry of this enrollment or not
* @param identity
* @param course
* @param userCourseEnv
* @return true if person already enrolled in one date, otherwise false
*/
protected boolean isAlreadyEnrolled(Identity identity, Collection<KalendarEvent> collEvents, DENCourseNode courseNode) {
boolean alreadyIn = false;
for( KalendarEvent event : collEvents ) {
//first check the correct course node and following if person is in
if(event.getSourceNodeId() != null) {
if(event.getSourceNodeId().equals(courseNode.getIdent()))//check the current course node
alreadyIn = isEnrolledInDate(identity, event);//check every event if the identity is already in
}
if(alreadyIn == true) break;//if identity is in any date enrolled, break and return true
}
return alreadyIn;
}
/**
* Checks if the number of maximum participants is reached
* @param event
* @return true if it is full, otherwise false
*/
protected boolean isDateFull(KalendarEvent event) {
if(event.getParticipants() != null) {
if(event.getNumParticipants() == event.getParticipants().length)
return true;
}
return false;
}
/**
* Returns all generated Events for this course and node
* @param courseId
* @param sourseNodeId
* @return List of all KalendarEvent in this date enrollment
*/
protected List<KalendarEvent> getDENEvents(Long courseId, String sourceNodeId) {
List<KalendarEvent> denEvents = new ArrayList<KalendarEvent>();
ICourse course = CourseFactory.loadCourse(courseId);
CalendarManager calManager = CoreSpringFactory.getImpl(CalendarManager.class);
Kalendar cal = calManager.getCourseCalendar(course).getKalendar();
Collection<KalendarEvent> colEvents = cal.getEvents();
for( KalendarEvent event : colEvents) {
String eventSourceNodeId = event.getSourceNodeId();
if(eventSourceNodeId != null) {
if(eventSourceNodeId.equals(sourceNodeId))
denEvents.add(event);
}
}
return denEvents;
}
/**
* Count of dates for this date enrollment
* @param courseRessourcableId
* @param courseNodeIdent
* @return number of dates
*/
public int getEventCount(Long courseId, String courseNodeId) {
if(courseId != null && courseNodeId != null) {
List<KalendarEvent> events = null;
try {
events = getDENEvents(courseId, courseNodeId);
} catch(Exception e) {
// nothing to do
}
if(events != null)
return events.size();
}
return 0;
}
/**
* This method generates the needed dates
* @param retakes
* @param durationStr
* @param pauseStr
* @param subjectStr
* @param commentStr
* @param locationStr
* @param begin
* @param numParticipants
* @param dataList
* @param denCourseNode
* @return List<KalendarEvent> with the generated dates
*/
protected List<KalendarEvent> generateDates(
String subjectStr, String commentStr, String locationStr, String durationStr, String pauseStr,
Date begin, int retakes, int numParticipants, List<KalendarEvent> dataList, String denCourseNodeId) {
Date nextEvent = null;
for (int i = 0; i < retakes; i++) {
StringTokenizer strTok = new StringTokenizer(durationStr, ":", false);
//duration in milliseconds
int duration = 1000*60*60*Integer.parseInt(strTok.nextToken()) + 1000*60*Integer.parseInt(strTok.nextToken());
strTok = new StringTokenizer(pauseStr, ":", false);
//pause in milliseconds
int pause = 1000*60*60*Integer.parseInt(strTok.nextToken()) + 1000*60*Integer.parseInt(strTok.nextToken());
KalendarEvent newEvent;
String evnetId = CodeHelper.getGlobalForeverUniqueID();
if(nextEvent == null) {
newEvent = new KalendarEvent(evnetId, subjectStr, begin, duration);
} else {
newEvent = new KalendarEvent(evnetId, subjectStr, nextEvent, duration);
}
newEvent.setNumParticipants(numParticipants);
newEvent.setLocation(locationStr);
newEvent.setComment(commentStr);
newEvent.setSourceNodeId(denCourseNodeId);
dataList.add(newEvent);
//prepare next Event
long newTime = newEvent.getEnd().getTime() + pause;
nextEvent = new Date(newTime);
}
return dataList;
}
/**
* Update one date in a list of KalendarEvents with the given informations from a manage dates form
* @param datesForm of type DENEditManageDatesForm
* @param dataList
* @param index
* @return list with actualized KalendarEvents
*/
protected List<KalendarEvent> updateDateInList(String subjectStr, String commentStr, String locationStr, String durationStr,
Date begin, int numParticipants, List<KalendarEvent> dataList, int index) {
StringTokenizer strTok = new StringTokenizer(durationStr, ":", false);
int duration = 1000*60*60*Integer.parseInt(strTok.nextToken()) + 1000*60*Integer.parseInt(strTok.nextToken());
KalendarEvent oldEvent = dataList.get(index);
KalendarEvent newEvent = new KalendarEvent(oldEvent.getID(), subjectStr, begin, duration);
newEvent.setNumParticipants(numParticipants);
newEvent.setLocation(locationStr);
newEvent.setComment(commentStr);
newEvent.setSourceNodeId(oldEvent.getSourceNodeId());
newEvent.setParticipants(oldEvent.getParticipants());
dataList.remove(index);
dataList.add(index, newEvent);
return dataList;
}
/**
* Update multiple dates in a list of KalendarEvents with the given informations from a manage dates form
* @param datesForm of type DENEditManageDatesForm
* @param dataList
* @param selectedDates
* @return list with actualized KalendarEvents
*/
protected List<KalendarEvent> updateMultipleDatesInList(String subjectStr, String commentStr, String locationStr, String movementGapStr,
int numParticipants, List<KalendarEvent> dataList, BitSet selectedDates) {
for (int i = 0; i < dataList.size(); i++) {
if(selectedDates.get(i)) {
KalendarEvent oldEvent = dataList.get(i);
StringTokenizer strTok = new StringTokenizer(movementGapStr.substring(1), ":", false);
int gap = 1000*60*60*Integer.parseInt(strTok.nextToken()) + 1000*60*Integer.parseInt(strTok.nextToken());
Date newBegin, newEnd;
if(movementGapStr.startsWith("+")) {
newBegin = new Date(oldEvent.getBegin().getTime() + gap);
newEnd = new Date(oldEvent.getEnd().getTime() + gap);
} else {
newBegin = new Date(oldEvent.getBegin().getTime() - gap);
newEnd = new Date(oldEvent.getEnd().getTime() - gap);
}
String eventId = oldEvent.getID();
KalendarEvent newEvent = new KalendarEvent(eventId, null, subjectStr.equals(new String()) ? oldEvent.getSubject() : subjectStr, newBegin, newEnd);
if(numParticipants != 0)
newEvent.setNumParticipants(numParticipants);
else
newEvent.setNumParticipants(oldEvent.getNumParticipants());
if(!locationStr.equals(new String()))
newEvent.setLocation(locationStr);
else
newEvent.setLocation(oldEvent.getLocation());
if(!commentStr.equals(new String()))
newEvent.setComment(commentStr);
else
newEvent.setComment(oldEvent.getComment());
newEvent.setParticipants(oldEvent.getParticipants());
newEvent.setSourceNodeId(oldEvent.getSourceNodeId());
dataList.remove(i);
dataList.add(i, newEvent);
}
}
return dataList;
}
/**
* Add this event in the calendar of an enrolled user
* @param newEvent
*/
private void addDateInUserCalendar(KalendarEvent newEvent) {
String[] participants = newEvent.getParticipants();
if(participants == null) return;//no users to update, cancel
BaseSecurity manager = BaseSecurityManager.getInstance();
CalendarManager calManager = CoreSpringFactory.getImpl(CalendarManager.class);
for( String participant : participants ) {
Identity identity = manager.findIdentityByName(participant);
if(identity != null) {
Kalendar userCal = calManager.getPersonalCalendar(identity).getKalendar();
List<KalendarEvent> userEvents = new ArrayList<>();
userEvents.addAll(userCal.getEvents());
String eventId = CodeHelper.getGlobalForeverUniqueID();
KalendarEvent userNewEvent = new KalendarEvent(eventId, null, newEvent.getSubject(), newEvent.getBegin(), newEvent.getEnd());
userNewEvent.setLocation(newEvent.getLocation());
userNewEvent.setSourceNodeId(newEvent.getSourceNodeId());
userNewEvent.setClassification(KalendarEvent.CLASS_PRIVATE);
List<KalendarEventLink> kalendarEventLinks = userNewEvent.getKalendarEventLinks();
kalendarEventLinks.clear();
kalendarEventLinks.addAll(newEvent.getKalendarEventLinks());
calManager.addEventTo(userCal, userNewEvent);
}
}
}
/**
* Removes this event in all calendars of enrolled users
* @param oldEvent
*/
private void removeDateInUserCalendar(KalendarEvent oldEvent) {
String[] participants = oldEvent.getParticipants();
if(participants == null) return;//no users to update, cancel
BaseSecurity manager = BaseSecurityManager.getInstance();
CalendarManager calManager = CoreSpringFactory.getImpl(CalendarManager.class);
for( String participant : participants ) {
Identity identity = manager.findIdentityByName(participant);
if(identity != null) {
Kalendar userCal = calManager.getPersonalCalendar(identity).getKalendar();
List<KalendarEvent> userEvents = new ArrayList<>();
userEvents.addAll(userCal.getEvents());
for( KalendarEvent userEvent : userEvents ) {
String sourceNodeId = userEvent.getSourceNodeId();
if(sourceNodeId != null && sourceNodeId.equals(oldEvent.getSourceNodeId())) {
calManager.removeEventFrom(userCal, userEvent);
}
}
}
}
}
/**
* Create the table for the manage dates view
* @param ureq
* @param wControl
* @param trans
* @param listener
* @param tableData DENEditTableDataModel
* @return TableController
*/
protected TableController createManageDatesTable(UserRequest ureq, WindowControl wControl, Translator trans, DENEditTableDataModel tableData) {
TableGuiConfiguration tableConfig = new TableGuiConfiguration();
tableConfig.setResultsPerPage(15);
tableConfig.setShowAllLinkEnabled(true);
TableController tableCntrl = new TableController(tableConfig, ureq, wControl, trans);
tableCntrl.addColumnDescriptor(new StrongColumnDescriptor("dates.table.date", 0, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.begin", 1, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new StrongColumnDescriptor("dates.table.location", 3, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.duration", 2, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.comment", 4, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.participants.num", 5, null, ureq.getLocale()));
tableCntrl.addMultiSelectAction("dates.table.edit.change", DENEditTableDataModel.CHANGE_ACTION);
tableCntrl.addMultiSelectAction("dates.table.edit.delete", DENEditTableDataModel.DELETE_ACTION);
tableCntrl.setMultiSelect(true);
tableCntrl.setTableDataModel(tableData);
tableCntrl.setSortColumn(2, true);//begin + multi select column
return tableCntrl;
}
/**
* Create the table for the run view
* @param ureq
* @param wControl
* @param trans
* @param listener
* @param tableData DENRunTableDataModel
* @return TableController
*/
protected TableController createRunDatesTable(UserRequest ureq, WindowControl wControl, Translator trans, DENRunTableDataModel tableData) {
TableGuiConfiguration tableConfig = new TableGuiConfiguration();
tableConfig.setTableEmptyMessage(trans.translate("dates.table.empty"));
TableController tableCntrl = new TableController(tableConfig, ureq, wControl, trans);
tableCntrl.addColumnDescriptor(new StrongColumnDescriptor("dates.table.date", 0, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.begin", 1, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new StrongColumnDescriptor("dates.table.location", 3, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.duration", 2, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.comment", 4, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.reserved", 5, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.status", 6, null, ureq.getLocale()));
if(tableData.isEnrollmentEnabled()) {
tableCntrl.addColumnDescriptor(new BooleanColumnDescriptor("dates.table.sign.in", 7, DENRunTableDataModel.CMD_ENROLL_IN_DATE,
trans.translate("dates.table.sign.in"), trans.translate("dates.table.run.no_action")));
tableCntrl.addColumnDescriptor(new BooleanColumnDescriptor("dates.table.sign.out", 8, DENRunTableDataModel.CMD_ENROLLED_CANCEL,
trans.translate("dates.table.sign.out"), trans.translate("dates.table.run.no_action")));
}
tableCntrl.setTableDataModel(tableData);
tableCntrl.setSortColumn(1, true);//timeframe
return tableCntrl;
}
/**
* Create the table for the list of participants view
* @param ureq
* @param wControl
* @param trans
* @param listener
* @param tableData DENListTableDataModel
* @return TableController
*/
protected TableController createListParticipantsTable(UserRequest ureq, WindowControl wControl, Translator trans, DENListTableDataModel tableData) {
TableGuiConfiguration tableConfig = new TableGuiConfiguration();
tableConfig.setTableEmptyMessage(trans.translate("dates.table.empty"));
TableController tableCntrl = new TableController(tableConfig, ureq, wControl, trans);
tableCntrl.addColumnDescriptor(new StrongColumnDescriptor("dates.table.date", 0, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.begin", 1, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new StrongColumnDescriptor("dates.table.location", 3, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.duration", 2, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.comment", 4, null, ureq.getLocale()));
DefaultColumnDescriptor dcd = new DefaultColumnDescriptor("dates.table.participant.name", 5, null, ureq.getLocale());
dcd.setEscapeHtml(EscapeMode.none);
tableCntrl.addColumnDescriptor(dcd);
boolean isAdministrativeUser = CoreSpringFactory.getImpl(BaseSecurityModule.class).isUserAllowedAdminProps(ureq.getUserSession().getRoles());
if(isAdministrativeUser) {
DefaultColumnDescriptor ucd = new DefaultColumnDescriptor("dates.table.participant.username", 6, null, ureq.getLocale());
ucd.setEscapeHtml(EscapeMode.none);
tableCntrl.addColumnDescriptor(ucd);
}
if(!tableData.isReadOnly()) {
tableCntrl.addColumnDescriptor(new BooleanColumnDescriptor("participants", 7, DENListTableDataModel.CHANGE_ACTION,
trans.translate("dates.table.participant.manage"), ""));
tableCntrl.addMultiSelectAction("dates.table.list.email", DENListTableDataModel.MAIL_ACTION);
tableCntrl.addMultiSelectAction("dates.table.list.delete", DENListTableDataModel.DELETE_ACTION);
tableCntrl.setMultiSelect(true);
}
tableCntrl.setTableDataModel(tableData);
tableCntrl.setSortColumn(2, true);//timeframe + multi select column
return tableCntrl;
}
/**
* Create the table for the participants management view
* @param ureq
* @param wControl
* @param trans
* @param listener
* @param tableData DENParticipantsTableDataModel
* @return TableController
*/
protected TableController createParticipantsTable(UserRequest ureq, WindowControl wControl, Translator trans, DENParticipantsTableDataModel tableData) {
TableGuiConfiguration tableConfig = new TableGuiConfiguration();
tableConfig.setTableEmptyMessage(trans.translate("dates.table.empty"));
TableController tableCntrl = new TableController(tableConfig, ureq, wControl, trans);
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.participant.firstname", 0, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.participant.lastname", 1, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new DefaultColumnDescriptor("dates.table.participant.email", 2, null, ureq.getLocale()));
tableCntrl.addColumnDescriptor(new BooleanColumnDescriptor("dates.table.participant.email.send", 3, DENParticipantsTableDataModel.MAIL_ACTION,
trans.translate("dates.table.participant.email.send"), ""));
tableCntrl.addColumnDescriptor(new BooleanColumnDescriptor("dates.table.list.delete", 3, DENParticipantsTableDataModel.REMOVE_ACTION,
trans.translate("dates.table.list.delete"), ""));
tableCntrl.setTableDataModel(tableData);
return tableCntrl;
}
/**
* Delete all participants in the events with the given IDs
* @param course
* @param courseNode
* @param eventIDs of the events, where all participants should be deleted
* @return list with the actualized events
*/
protected List<KalendarEvent> deleteParticipants(OLATResourceable ores, DENCourseNode courseNode, List<String> eventIDs) {
List<KalendarEvent> events = getDENEvents(ores.getResourceableId(), courseNode.getIdent());
for( KalendarEvent event : events ) {
if(eventIDs.contains(event.getID())) {
removeDateInUserCalendar(event);
event.setParticipants(new String[0]);
}
}
persistDENSettings(events, ores, courseNode);
return events;
}
/**
* Little helper method, that gives you all IDs of the selected events in the list
* @param dataList
* @param selection BitSet
* @return list of strings with IDs
*/
protected List<String> getSelectedEventIDs(List<KalendarEvent> dataList, BitSet selection) {
List<String> lstIDs = new ArrayList<String>();
for(int i = 0; i < dataList.size(); i++) {
if(selection.get(i)) {
lstIDs.add(dataList.get(i).getID());
}
}
return lstIDs;
}
/**
* Little helper method, that gives you all participants of the selected events in the list
* @param dataList
* @param selection BitSet
* @return list of Identities
*/
protected List<Identity> getSelectedEventParticipants(List<KalendarEvent> dataList, BitSet selection) {
List<Identity> identities = new ArrayList<Identity>();
BaseSecurity manager = BaseSecurityManager.getInstance();
for(int i = 0; i < dataList.size(); i++) {
if(selection.get(i)) {
String[] parts = dataList.get(i).getParticipants();
if(parts != null) {
for(String participant : parts) {
Identity identity = manager.findIdentityByName(participant);
if(identity != null) {
identities.add(identity);
}
}
}
}
}
return identities;
}
/**
* Little helper method, that gives you all participants of a specific event
* @param event
* @return list of Identities
*/
protected List<Identity> getEventParticipants(KalendarEvent event) {
List<Identity> identities = new ArrayList<Identity>();
List<KalendarEvent> lstEvent = new ArrayList<KalendarEvent>();
lstEvent.add(event);
BitSet selection = new BitSet(1);
selection.set(0);
identities = getSelectedEventParticipants(lstEvent, selection);
return identities;
}
/**
* Generates the mail window
* @param ureq
* @param wControl
* @param listener
* @param velocity_root
* @param trans
* @param participants
* @return VelocityContainer
*/
protected VelocityContainer sendParticipantsMessage(UserRequest ureq, WindowControl wControl, DefaultController listener, String velocity_root, Translator trans, List<Identity> participants) {
VelocityContainer sendMessageVC = new VelocityContainer("sendmessage", velocity_root + "/sendmessage.html", trans, listener);
ContactMessage cmsg = new ContactMessage(ureq.getIdentity());
ContactList contactList = null;
if(participants.size() == 1) {
contactList = new ContactList(participants.get(0).getUser().getProperty(UserConstants.EMAIL, ureq.getLocale()));
} else {
contactList = new ContactList(trans.translate("participants.message.to"));
}
contactList.addAllIdentites(participants);
cmsg.addEmailTo(contactList);
ContactFormController contactCtr = new ContactFormController(ureq, wControl, false, false, false, cmsg);
contactCtr.addControllerListener(listener);
sendMessageVC.contextPut("title", trans.translate("participants.message"));
sendMessageVC.put("contactForm", contactCtr.getInitialComponent());
return sendMessageVC;
}
/**
* Generates the duration as string
* @param event
* @return String with duration in format "hh:mm"
*/
protected String getDurationAsString(KalendarEvent event) {
Date begin = event.getBegin();
Date end = event.getEnd();
long duration = end.getTime() - begin.getTime();
long hours = (long)Math.floor(duration / 1000 / 60 / 60);
long minutes = (duration / 1000 / 60 % 60);
StringBuilder sbHours = new StringBuilder();
StringBuilder sbMinutes = new StringBuilder();
if(hours < 10)
sbHours.append(0);
if(minutes < 10)
sbMinutes.append(0);
sbHours.append(hours);
sbMinutes.append(minutes);
//in case of failure
if(sbHours.length() > 2 || sbMinutes.length() > 2)
return "00:00";
return new String(sbHours + ":" + sbMinutes);
}
/**
* Generates a mail template for users who were added to a date
* @param identity
* @param event
* @param translator
* @return MailTemplate
*/
protected MailTemplate getAddedMailTemplate(UserRequest ureq, String subjectStr, Translator translator) {
Identity identity = ureq.getIdentity();
String[] bodyArgs = new String[] {
identity.getUser().getProperty(UserConstants.FIRSTNAME, ureq.getLocale()),
identity.getUser().getProperty(UserConstants.LASTNAME, ureq.getLocale()),
identity.getUser().getProperty(UserConstants.EMAIL, ureq.getLocale()),
"", subjectStr
};
String subject = translator.translate("mail.participants.add.subject", bodyArgs);
String body = translator.translate("mail.participants.add.body", bodyArgs);
MailTemplate mailTempl = new MailTemplate(subject, body, null) {
@Override
public void putVariablesInMailContext(VelocityContext context, Identity ident) {
//
}
};
return mailTempl;
}
/**
* Generates a mail template for users who were removed from a date
* @param identity
* @param event
* @param trans
* @return MailTemplate
*/
protected MailTemplate getRemovedMailTemplate(UserRequest ureq, String subjectStr, Translator trans) {
Identity identity = ureq.getIdentity();
String[] bodyArgs = new String[] {
identity.getUser().getProperty(UserConstants.FIRSTNAME, ureq.getLocale()),
identity.getUser().getProperty(UserConstants.LASTNAME, ureq.getLocale()),
identity.getUser().getProperty(UserConstants.EMAIL, ureq.getLocale()),
"", subjectStr
};
String subject = trans.translate("mail.participants.remove.subject", bodyArgs);
String body = trans.translate("mail.participants.remove.body", bodyArgs);
MailTemplate mailTempl = new MailTemplate(subject, body, null) {
@Override
public void putVariablesInMailContext(VelocityContext context, Identity ident) {
//
}
};
return mailTempl;
}
/*
* Helper methods
*/
private boolean isSubstringInStringArray(String str, String[] strArr) {
for( String tmpStr : strArr ) {
if (str.equals(tmpStr)) return true;
}
return false;
}
private void createKalendarEventLinks(ICourse course, DENCourseNode courseNode, KalendarEvent event) {
List<KalendarEventLink> kalendarEventLinks = event.getKalendarEventLinks();
RepositoryEntry re = RepositoryManager.getInstance().lookupRepositoryEntry(course, true);
OLATResourceable oresNode = OresHelper.createOLATResourceableInstance("CourseNode", Long.valueOf(courseNode.getIdent()));
List<ContextEntry> ces = new ArrayList<ContextEntry>();
ces.add(BusinessControlFactory.getInstance().createContextEntry(re));
ces.add(BusinessControlFactory.getInstance().createContextEntry(oresNode));
String extLink = BusinessControlFactory.getInstance().getAsURIString(ces, false);
String iconCssClass = CourseNodeFactory.getInstance().getCourseNodeConfiguration(courseNode.getType()).getIconCSSClass();
KalendarEventLink link = new KalendarEventLink("COURSE", courseNode.getIdent(), courseNode.getShortTitle(), extLink, iconCssClass);
kalendarEventLinks.clear();
kalendarEventLinks.add(link);
}
public String formatDuration(long ms, Translator translator) {
boolean setEntry = false;
int day = (int)(ms/1000/60/60/24);
int hour = (int)((ms - (day*24*60*60*1000))/1000/60/60);
int min = (int)((ms - (day*24*60*60*1000) - (hour*60*60*1000))/1000/60);
StringBuilder sb = new StringBuilder();
if (day != 0) {
sb.append(day);
sb.append(" ");
if (day > 1) {
sb.append(translator.translate("table.model.duration.days"));
} else {
sb.append(translator.translate("table.model.duration.day"));
}
setEntry = true;
}
if (hour != 0) {
if (day != 0) sb.append(" ");
sb.append(hour);
sb.append(" ");
if (hour > 1) {
sb.append(translator.translate("table.model.duration.hours"));
} else {
sb.append(translator.translate("table.model.duration.hour"));
}
setEntry = true;
}
if (min != 0) {
if (day != 0 || hour != 0) sb.append(" ");
sb.append(min);
sb.append(" ");
if (min > 1) {
sb.append(translator.translate("table.model.duration.mins"));
} else {
sb.append(translator.translate("table.model.duration.min"));
}
setEntry = true;
}
if (!setEntry) {
sb.append("0 ");
sb.append(translator.translate("table.model.duration.min"));
}
return sb.toString();
}
public long getDuration(Date begin, Date end) {
if(end.before(begin)) return getDuration(end, begin);
return end.getTime() - begin.getTime();
}
}