//<OLATCE-103>
/**
* <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.vc.provider.wimba;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.components.link.LinkFactory;
import org.olat.core.gui.components.table.DefaultColumnDescriptor;
import org.olat.core.gui.components.table.StaticColumnDescriptor;
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.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.media.RedirectMediaResource;
import org.olat.core.gui.translator.Translator;
/**
*
* Description:<br>
* Display controller for Wimba Classroom usage at run-time
*
* <P>
* Initial Date: 06.01.2011 <br>
* @author skoeber
*/
public class WimbaDisplayController extends BasicController {
private static String COMMAND_JOIN_MODERATOR = "cmd.join.moderator";
private static String COMMAND_JOIN_LEARNER = "cmd.join.learner";
private static String COMMAND_JOIN_GUEST = "cmd.join.guest";
private static String COMMAND_START_MEETING = "cmd.start.meeting";
private static String COMMAND_CLOSE_MEETING = "cmd.close.meeting";
private static String COMMAND_UNCLOSE_MEETING = "cmd.unclose.meeting";
private static String COMMAND_UPDATE_MEETING = "cmd.update.meeting";
private static String COMMAND_OPEN_MANAGEROOM = WimbaClassroomProvider.TARGET_OPEN_MANAGEROOM;
private static String COMMAND_OPEN_POLLRESULTS = WimbaClassroomProvider.TARGET_OPEN_POLLRESULTS;
private static String COMMAND_OPEN_TRACKING = WimbaClassroomProvider.TARGET_OPEN_TRACKING;
private static String COMMAND_OPEN_WIZARD = WimbaClassroomProvider.TARGET_OPEN_WIZARD;
private static String COMMAND_OPEN_RECORDING = "cmd.open.recording";
private static String COMMAND_TOGGLESTATUS_RECORDING = "cmd.togglestatus.recording";
private static String COMMAND_DELETE_RECORDING = "cmd.delete.recording";
// GUI
private VelocityContainer runVC;
private Link joinModerator, joinLearner, joinGuest;
private Link startMeeting, closeMeeting, uncloseMeeting, updateMeeting;
private Link openWizard, openManageRoom, openPollResults, openTracking;
private TableController recTable;
//data
private WimbaClassroomConfiguration config;
private String name, description;
private String roomId;
private RecordingsTableModel recTableModel;
private WimbaClassroomProvider wimba;
protected WimbaDisplayController(UserRequest ureq, WindowControl wControl, String roomId, String name, String description, boolean isModerator,
WimbaClassroomConfiguration config, WimbaClassroomProvider provider) {
super(ureq, wControl);
this.wimba = provider;
this.config = config;
this.roomId = roomId;
this.name = name;
this.description = description;
runVC = createVelocityContainer("run");
boolean exists = wimba.existsClassroom(roomId, config);
boolean closed = exists ? wimba.isPreviewMode(roomId, false) : false;
boolean isGuest = ureq.getUserSession().getRoles().isGuestOnly();
boolean showGuestLink = config.isGuestAccessAllowed();
if(isModerator) {
wimba.createModerator(ureq.getIdentity(), roomId);
} else if(!isGuest) {
wimba.createUser(ureq.getIdentity(), roomId);
}
String guestLink = wimba.createClassroomGuestUrl(roomId, ureq.getIdentity(), config).toString();
joinModerator = LinkFactory.createButton(COMMAND_JOIN_MODERATOR, runVC, this);
joinLearner = LinkFactory.createButton(COMMAND_JOIN_LEARNER, runVC, this);
joinGuest = LinkFactory.createButton(COMMAND_JOIN_GUEST, runVC, this);
startMeeting = LinkFactory.createButton(COMMAND_START_MEETING, runVC, this);
closeMeeting = LinkFactory.createButton(COMMAND_CLOSE_MEETING, runVC, this);
uncloseMeeting = LinkFactory.createButton(COMMAND_UNCLOSE_MEETING, runVC, this);
updateMeeting = LinkFactory.createButton(COMMAND_UPDATE_MEETING, runVC, this);
// set target to be able to open new browser window on event
joinGuest.setTarget("_blank");
joinLearner.setTarget("_blank");
joinModerator.setTarget("_blank");
joinLearner.setEnabled(!closed);
joinGuest.setEnabled(!closed);
runVC.contextPut("exists", exists);
runVC.contextPut("closed", closed);
runVC.contextPut("isGuest", isGuest);
runVC.contextPut("isModerator", isModerator);
runVC.contextPut("showGuestLink", showGuestLink);
runVC.contextPut("guestLink", guestLink);
// convenience links
openWizard = LinkFactory.createButton(COMMAND_OPEN_WIZARD, runVC, this);
openWizard.setTarget("_blank");
// moderator links
if(isModerator) {
openManageRoom = LinkFactory.createButton(COMMAND_OPEN_MANAGEROOM, runVC, this);
openPollResults = LinkFactory.createButton(COMMAND_OPEN_POLLRESULTS, runVC, this);
openTracking = LinkFactory.createButton(COMMAND_OPEN_TRACKING, runVC, this);
openManageRoom.setTarget("_blank");
openPollResults.setTarget("_blank");
openTracking.setTarget("_blank");
}
// show recordings
TableGuiConfiguration tableConfig = new TableGuiConfiguration();
tableConfig.setDisplayRowCount(true);
tableConfig.setPageingEnabled(true);
tableConfig.setTableEmptyMessage(translate("table.recordings.empty"));
recTable = new TableController(tableConfig, ureq, wControl, getTranslator());
DefaultColumnDescriptor recCol = new DefaultColumnDescriptor("table.recordings.name", 1, COMMAND_OPEN_RECORDING, getLocale());
recCol.setIsPopUpWindowAction(true, null);
recTable.addColumnDescriptor(recCol);
if(isModerator) {
recTable.addColumnDescriptor(new DefaultColumnDescriptor("table.recordings.status", 2, COMMAND_TOGGLESTATUS_RECORDING, getLocale()));
recTable.addColumnDescriptor(new StaticColumnDescriptor(COMMAND_DELETE_RECORDING, "table.recordings.action", translate("table.recordings.delete")));
}
Map<String, String> recordings = wimba.listRecordings(roomId);
List<String> keys = new ArrayList<String>(recordings.keySet());
Collections.sort(keys);
List<Object[]> recordingData = new ArrayList<Object[]>();
for(String key : keys) {
String title = recordings.get(key);
boolean preview = wimba.isPreviewMode(key, true);
/*
* for moderators: add all recordings and show actions
* for users: add only recordings that are not in preview mode
*/
if(!preview | isModerator) recordingData.add(new Object[] {key, title, preview});
}
recTableModel = new RecordingsTableModel(recordingData, getTranslator());
recTable.setTableDataModel(recTableModel);
listenTo(recTable);
runVC.put("recordingsTable", recTable.getInitialComponent());
putInitialPanel(runVC);
}
@Override
protected void event(UserRequest ureq, Component source, Event event) {
if(source == startMeeting) {
boolean success = wimba.createClassroom(roomId, name, description, null, null, config);
if(success) {
runVC.contextPut("exists", true);
runVC.setDirty(true);
} else {
getWindowControl().setError(translate("error.create.room"));
}
} else if(source == joinModerator) {
boolean success = wimba.existsClassroom(roomId, config);
// update rights for user to moderate meeting
if(success) {
success = wimba.createModerator(ureq.getIdentity(), roomId);
} else {
// room not found, should not appear
getWindowControl().setError(translate("error.no.room"));
return;
}
// login the user as moderator
if(success) {
success = wimba.login(ureq.getIdentity(), null);
} else {
// could not create moderator or update the rights
getWindowControl().setError(translate("error.update.rights"));
return;
}
// redirect to the meeting
if(success) {
joinMeeting(ureq, false);
} else {
// login failed
getWindowControl().setError(translate("error.no.login"));
return;
}
return;
} else if(source == joinLearner) {
joinMeeting(ureq, false);
return;
} else if(source == joinGuest) {
joinMeeting(ureq, true);
return;
} else if(source == closeMeeting) {
boolean success = wimba.setPreviewMode(roomId, true, false);
if(success) {
runVC.contextPut("closed", true);
runVC.setDirty(true);
} else {
// closing failed
getWindowControl().setError(translate("error.remove.room"));
}
} else if(source == uncloseMeeting) {
boolean success = wimba.setPreviewMode(roomId, false, false);
if(success) {
runVC.contextPut("closed", false);
runVC.setDirty(true);
} else {
// reopen failed
getWindowControl().setError(translate("error.update.room"));
}
} else if(source == updateMeeting) {
boolean success = wimba.updateClassroom(roomId, name, description, null, null, config);
if(success) {
getWindowControl().setInfo(translate("success.update.room"));
} else {
// update failed
getWindowControl().setError(translate("error.update.room"));
}
} else if(source == openWizard | source == openManageRoom | source == openPollResults | source == openTracking) {
openWimbaUrl(ureq, ((Link)source).getCommand());
return;
}
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if(source == recTable) {
if(event instanceof TableEvent) {
TableEvent tEvent = (TableEvent)event;
String action = tEvent.getActionId();
int row = tEvent.getRowId();
String key = (String) recTable.getTableDataModel().getValueAt(row, 0);
if(action.equals(COMMAND_OPEN_RECORDING)) {
wimba.login(ureq.getIdentity(), null);
URL url = wimba.createClassroomRecordingUrl(key, ureq.getIdentity());
RedirectMediaResource rmr = new RedirectMediaResource(url.toString());
ureq.getDispatchResult().setResultingMediaResource(rmr);
return;
} else if(action.equals(COMMAND_TOGGLESTATUS_RECORDING)) {
Object[] entry = (Object[]) recTable.getTableDataModel().getObject(row);
Boolean preview = (Boolean) entry[2];
if(wimba.setPreviewMode(key, !preview, true)) {
String text = preview ? "table.recordings.unclose.success" : "table.recordings.close.success";
getWindowControl().setInfo(translate(text));
recTableModel.toggleStatus(row);
recTable.modelChanged();
runVC.setDirty(true);
} else {
String text = preview ? "table.recordings.unclose.error" : "table.recordings.close.error";
getWindowControl().setError(translate(text));
}
} else if(action.equals(COMMAND_DELETE_RECORDING)) {
if(wimba.removeClassroomRecording(key)) {
getWindowControl().setInfo(translate("table.recordings.delete.success"));
recTableModel.removeRecording(row);
recTable.modelChanged();
runVC.setDirty(true);
} else {
getWindowControl().setError(translate("table.recordings.delete.error"));
}
}
}
}
}
private void openWimbaUrl(UserRequest ureq, String target) {
boolean success = false;
if (target.equals(COMMAND_OPEN_WIZARD)) {
String url = wimba.createServiceUrl(target, null);
RedirectMediaResource rmr = new RedirectMediaResource(url);
ureq.getDispatchResult().setResultingMediaResource(rmr);
}
else {
success = wimba.createModerator(ureq.getIdentity(), roomId);
if(success) {
wimba.login(ureq.getIdentity(), null);
String url = wimba.createServiceUrl(target, roomId);
RedirectMediaResource rmr = new RedirectMediaResource(url);
ureq.getDispatchResult().setResultingMediaResource(rmr);
} else {
// could not create moderator or update the rights
getWindowControl().setError(translate("error.update.rights"));
return;
}
}
}
private void joinMeeting(UserRequest ureq, boolean guest) {
URL url;
if(guest) {
url = wimba.createClassroomGuestUrl(roomId, ureq.getIdentity(), config);
} else {
boolean success = wimba.login(ureq.getIdentity(), null);
// no success, maybe the user account doesn't exist, create it and try the login again
if(!success) wimba.createUser(ureq.getIdentity(), roomId);
wimba.login(ureq.getIdentity(), null);
url = wimba.createClassroomUrl(roomId, ureq.getIdentity(), config);
}
RedirectMediaResource rmr = new RedirectMediaResource(url.toString());
ureq.getDispatchResult().setResultingMediaResource(rmr);
}
@Override
protected void doDispose() {
// nothing to dispose
}
}
class RecordingsTableModel implements TableDataModel<Object[]> {
private List<Object[]> recordings = new ArrayList<Object[]>();
private Translator translator;
public RecordingsTableModel(List<Object[]> recordings, Translator translator) {
this.recordings.addAll(recordings);
this.translator = translator;
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public int getRowCount() {
return recordings.size();
}
@Override
public Object getValueAt(int row, int col) {
Object[] recording = this.recordings.get(row);
switch(col) {
case 0: return recording[col];//key
case 1: return recording[col];//title
case 2: //action string depending on status
Boolean preview = (Boolean) recording[col];
return preview
? translator.translate("table.recordings.unclose")
: translator.translate("table.recordings.close");
default: return recording[col];
}
}
@Override
public Object[] getObject(int row) {
return recordings.get(row);
}
@Override
public void setObjects(List<Object[]> objects) {
this.recordings = objects;
}
@Override
public Object createCopyWithEmptyList() {
// not used
return "";
}
public void removeRecording(int row) {
this.recordings.remove(row);
}
public void toggleStatus(int row) {
Boolean status = (Boolean) this.recordings.get(row)[2];
this.recordings.get(row)[2] = !status;
}
}
//</OLATCE-103>