Permalink
Browse files

Merged LMSUZH-578

  • Loading branch information...
OLAT Team
OLAT Team committed Feb 1, 2018
2 parents aff0da1 + e6070bc commit 23abe4ee76803a8ea756f5de55d07b918f5bd192
Showing with 188 additions and 91 deletions.
  1. +2 −0 ...extension-adobeconnect/src/main/java/ch/uzh/extension/adobeconnect/client/AdobeConnectClient.java
  2. +92 −22 ...n-adobeconnect/src/main/java/ch/uzh/extension/adobeconnect/client/LmsuzhSwitchInteractClient.java
  3. +0 −31 ...n-adobeconnect/src/main/java/ch/uzh/extension/adobeconnect/client/LmsuzhSwitchInteractConfig.java
  4. +1 −5 lmsuzh-extension-adobeconnect/src/main/java/ch/uzh/extension/adobeconnect/client/model/Meeting.java
  5. +1 −1 ...-adobeconnect/src/main/java/ch/uzh/extension/adobeconnect/presentation/MeetingEditController.java
  6. +45 −7 ...c/main/java/ch/uzh/extension/adobeconnect/presentation/admin/SwitchInteractCleanupController.java
  7. +2 −1 ...in/java/ch/uzh/extension/adobeconnect/presentation/admin/SwitchInteractSystemAdminController.java
  8. +1 −1 ...main/java/ch/uzh/extension/adobeconnect/translation/language/SwitchInteractFrenchTranslation.java
  9. +1 −1 ...ain/java/ch/uzh/extension/adobeconnect/translation/language/SwitchInteractItalianTranslation.java
  10. +10 −5 ...connect/src/main/resources/ch/uzh/extension/adobeconnect/presentation/admin/_content/cleanup.html
  11. +8 −2 .../main/resources/ch/uzh/extension/adobeconnect/presentation/admin/_i18n/LocalStrings_de.properties
  12. +9 −3 .../main/resources/ch/uzh/extension/adobeconnect/presentation/admin/_i18n/LocalStrings_en.properties
  13. +8 −2 .../main/resources/ch/uzh/extension/adobeconnect/presentation/admin/_i18n/LocalStrings_fr.properties
  14. +8 −2 .../main/resources/ch/uzh/extension/adobeconnect/presentation/admin/_i18n/LocalStrings_it.properties
  15. +0 −4 lmsuzh-extension-adobeconnect/src/main/resources/switchinteract.properties
  16. +0 −4 lmsuzh-extension-adobeconnect/src/main/resources/switchinteract.properties.template
@@ -106,6 +106,7 @@ public Response getFilteredAction(String action, FilterParameter filter) {
public Response getAction(String action, HashMap<String, String> params) {
WebTarget wt = prepareTargetWithParametrizedAction(action, params);
LOG.debug(wt.getUri().toString());
System.out.println(wt.getUri().toString());
return wt.request().get();
}
@@ -826,6 +827,7 @@ private String getFirstElementValue(Element parent, String tagName) {
private Document parseResponse(String responseXml) throws Exception {
LOG.debug(responseXml);
//System.out.println(responseXml);
try {
Document doc = getDocumentFromResponse(responseXml);
NodeList nodes = doc.getElementsByTagName("status");
@@ -159,31 +159,13 @@ public void checkAllMemberships(Identity identity) {
RepositoryManager repositoryManager = CoreSpringFactory.getImpl(RepositoryManager.class);
HashMap<String, String> processedCourses = new HashMap<>();
try {
List<RepositoryEntry> entriesAsOwner = repositoryManager.queryByOwner(identity);
for (RepositoryEntry re : entriesAsOwner) {
List<RepositoryEntry> entries = repositoryManager.queryByMembership(identity, true, true, true);
for (RepositoryEntry re : entries) {
String courseId = re.getOlatResource().getResourceableId().toString();
if (!processedCourses.containsKey(courseId)) {
checkMembershipsInCourse(principalId, courseId, re.getAccess(), Meeting.Permission.HOST);
processedCourses.put(courseId, courseId);
syncCourseMeetingsPermissions(courseId);
}
}
List<RepositoryEntry> entriesAsTeacher = repositoryManager.getLearningResourcesAsTeacher(identity, 0, -1);
for (RepositoryEntry re : entriesAsTeacher) {
String courseId = re.getResourceableId().toString();
if (!processedCourses.containsKey(courseId)) {
checkMembershipsInCourse(principalId, courseId, re.getAccess(), Meeting.Permission.PRESENTER);
processedCourses.put(courseId, courseId);
}
}
List<RepositoryEntry> entriesAsStudent = repositoryManager.getLearningResourcesAsStudent(identity, "CourseModule", 0, -1);
for (RepositoryEntry re : entriesAsStudent) {
String courseId = re.getOlatResource().getResourceableId().toString();
if (!processedCourses.containsKey(courseId)) {
checkMembershipsInCourse(principalId, courseId, re.getAccess(), Meeting.Permission.PARTICIPANT);
processedCourses.put(courseId, courseId);
}
}
/*
For documentation's sake, here is a selection of repositoryManager methods to get list of repo entries:
@@ -291,7 +273,7 @@ private String prependWithEnvironmentName(String baseName) {
public String getEnvironmentName() {
String envNameFromConfig = switchInteractModule.getEnvName();
String activeProfiles = StringUtils.join(env.getActiveProfiles());
return envNameFromConfig == "" ? activeProfiles : envNameFromConfig.concat("-").concat(activeProfiles);
return "".equals(envNameFromConfig) ? activeProfiles : envNameFromConfig.concat("-").concat(activeProfiles);
}
public List<Meeting> getCourseElementMeetings(String courseId, String nodeIdent, boolean withContentCount) {
@@ -345,6 +327,94 @@ private void checkTechnicalUserAccessInMyMeetings() {
}
}
private void prepareMeetingParticipants(
HashMap<String, String> participantsList,
String permission,
List<Identity> identities,
HashMap<Long, AdobeConnectPrincipal> adobeConnectPrincipalHashMap
) {
for (Identity identity : identities) {
AdobeConnectPrincipal principal = adobeConnectPrincipalHashMap.get(identity.getKey());
if (principal != null) {
String principalId = principal.getPrincipalId();
if (principalId != null && !participantsList.containsKey(principalId)) {
participantsList.put(principalId, permission);
}
}
}
}
public void syncCourseMeetingsPermissions(String courseId) {
RepositoryManager rm = RepositoryManager.getInstance();
ICourse course = CourseFactory.loadCourse(Long.parseLong(courseId));
RepositoryEntry entry = rm.lookupRepositoryEntry(course, true);
// find out who are the course participants (in three different roles)
List<Identity> owners = repositoryEntryRelationDao.getMembers(entry, RepositoryEntryRelationType.defaultGroup, GroupRoles.owner.name());
List<Identity> coaches = repositoryEntryRelationDao.getMembers(entry, RepositoryEntryRelationType.both, GroupRoles.coach.name());
List<Identity> participants = repositoryEntryRelationDao.getMembers(entry, RepositoryEntryRelationType.both, GroupRoles.participant.name());
// For those OLAT users that logged into SWITCH at least ones, we know mapping between OLAT identity and SWITCH principal;
// let's now build a map for future use for all course participants
List<Long> identityKeys = getIdentityKeys(owners, coaches, participants); // gather all identities to make only one DB request
List<AdobeConnectPrincipal> adobeConnectPrincipals = getAdobeConnectPrincipalsByIdentityKeys(identityKeys);
HashMap<Long, AdobeConnectPrincipal> adobeConnectPrincipalHashMap = buildIdentityKeyToAdobeConnectPrincipalHashMap(adobeConnectPrincipals);
// We will prepare a map of user permissions to persist in SWITCH via API calls
HashMap<String, String> basePermissionChanges = new HashMap<>();
// Get a list of all OLAT users that can be registered for this meeting. This is the state that we want to sync into SWITCH
prepareMeetingParticipants(basePermissionChanges, Meeting.Permission.HOST, owners, adobeConnectPrincipalHashMap);
prepareMeetingParticipants(basePermissionChanges, Meeting.Permission.PRESENTER, coaches, adobeConnectPrincipalHashMap);
prepareMeetingParticipants(basePermissionChanges, Meeting.Permission.PARTICIPANT, participants, adobeConnectPrincipalHashMap);
int courseAccess = entry.getAccess();
String technicalUserPrincipalId = getTechnicalPrincipalId();
// We sync all meetings (for given course) the same way
for (String folderId : getCourseMeetingFolderIds(courseId)) {
for (Meeting meeting : technicalUserClient.getMeetingsInFolder(folderId)) {
String scoId = meeting.getScoId();
if (scoId != null) {
// copy initial permissionChanges from the common base
HashMap<String, String> permissionChanges = new HashMap<>(basePermissionChanges);
// Get a currently valid list of SWITCH participants for the meeting.
List<Principal> meetingUsers = getTechnicalUserClient().getPermittedMeetingUsers(scoId);
// Find delta between lists of participants in OLAT and SWITCH
for (Principal meetingUser : meetingUsers) {
String principalId = meetingUser.getPrincipalId();
if (principalId != null) {
if (permissionChanges.containsKey(principalId)) {
if (NullUtil.notNullOrEmpty(meetingUser.getMeetingPermission()).equals(permissionChanges.get(principalId))) {
// nothing is changed comparing to Status Quo
// => remove item from permissionChanges to save an API call that changes nothing
permissionChanges.remove(principalId);
} // Otherwise, keep item in permissionChanges because permission was upgraded or downgraded
} else {
// Possibly, the user was once a member of OLAT course but has been removed later
// => explicitly remove it from SWITCH meeting too
if (!principalId.equals(technicalUserPrincipalId)) { // technical user should not be removed!!!
permissionChanges.put(principalId, Meeting.Permission.REMOVE);
}
}
}
}
// Synchronize delta
if (permissionChanges.size() > 0) {
for (String principalId : permissionChanges.keySet()) {
setMeetingPermission(scoId, principalId, permissionChanges.get(principalId));
}
}
// Set 'public' or 'managed' access for SWITCHinteract meeting depending on course access options
if (courseAccess >= RepositoryEntry.ACC_USERS) {
technicalUserClient.setPublicAccess(scoId);
} else {
technicalUserClient.setManagedAccess(scoId);
}
}
}
}
}
private void setMeetingPermissions(String scoId, String courseId) {
RepositoryManager rm = RepositoryManager.getInstance();
ICourse course = CourseFactory.loadCourse(Long.parseLong(courseId));

This file was deleted.

Oops, something went wrong.
@@ -14,11 +14,7 @@
public static final String HOST = "host";
public static final String PRESENTER = "mini-host";
public static final String PARTICIPANT = "view";
}
public class IsMember {
public static final String TRUE = "true";
public static final String FALSE = "false";
public static final String REMOVE = "remove";
}
@Nullable
@@ -66,7 +66,7 @@ public MeetingEditController(UserRequest ureq, WindowControl control, LmsuzhTran
@RequiresNonNull("uifactory")
@EnsuresNonNull("displayNameElement")
protected void initForm(@UnderInitialization MeetingEditController this, FormItemContainer formLayout, @UnknownInitialization Controller listener, UserRequest ureq) {
uifactory.addStaticTextElement("large.meeting.warning", "", formLayout);
uifactory.addStaticTextElement("large.meeting.warning", "", translate("large.meeting.warning"), formLayout);
String initialName = (meetingTableRow != null)
? meetingTableRow.getName()
: translate("new.meeting");
@@ -1,5 +1,6 @@
package ch.uzh.extension.adobeconnect.presentation.admin;
import ch.uzh.extension.adobeconnect.client.AdobeConnectClient;
import ch.uzh.extension.adobeconnect.client.LmsuzhSwitchInteractClient;
import ch.uzh.extension.adobeconnect.client.model.ContentFull;
import ch.uzh.extension.adobeconnect.client.model.Meeting;
@@ -15,12 +16,14 @@
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.FormUIFactory;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModelImpl;
import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
@@ -35,6 +38,7 @@
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class SwitchInteractCleanupController extends FormBasicController {
@@ -46,6 +50,7 @@
private DialogBoxController dialogBox;
private FlexiTableElement meetingsTable;
private MeetingTableDataModel meetingsTableModel;
private FormLink deleteSelectedButton;
private MeetingEditController editMeetingCtrl;
@SuppressWarnings({"method.invocation.invalid", "initialization.fields.uninitialized"})
@@ -87,6 +92,8 @@ protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event
doShowMeetingDetails(ureq, row);
}
}
} else if (deleteSelectedButton == source) {
doConfirmDeleteMultipleMeetings(ureq);
}
super.formInnerEvent(ureq, source, event);
}
@@ -95,8 +102,22 @@ protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event
protected void event(UserRequest ureq, Controller source, Event event) {
if (source == dialogBox) {
if (DialogBoxUIFactory.isYesEvent(event)) {
if (switchInteractClient.deleteMeeting(dialogBox.getUserObject().toString())) {
updateMeetingsTable();
Object userObject = dialogBox.getUserObject();
if (userObject instanceof Set) {
Set<Integer> selected = (Set<Integer>) userObject;
int deleted = 0;
for (Integer rowNo : selected) {
MeetingTableRow meetingRow = meetingsTableModel.getObject(rowNo.intValue());
String scoId = meetingRow.getScoId();
deleted += (switchInteractClient.deleteMeeting(scoId) ? 1 : 0);
}
if (deleted > 0) {
updateMeetingsTable();
}
} else {
if (switchInteractClient.deleteMeeting(dialogBox.getUserObject().toString())) {
updateMeetingsTable();
}
}
}
}
@@ -120,12 +141,29 @@ protected MeetingTableDataModel createTableModel(List<Meeting> meetings) {
}
public void updateMeetingsTable() {
List<Meeting> meetings = (switchInteractClient != null) ? switchInteractClient.getTechnicalUserClient().getMyMeetings() : new ArrayList<>();
meetingsTableModel = createTableModel(meetings);
meetingsTable = FormUIFactory.getInstance().addTableElement(getWindowControl(), "meetingsTable", meetingsTableModel, getTranslator(), flc);
meetingsTable.setEmtpyTableMessageKey("table.empty");
if (switchInteractClient != null) {
AdobeConnectClient technicalUserClient = switchInteractClient.getTechnicalUserClient();
if (technicalUserClient != null && switchInteractClient.isAvailable()) {
List<Meeting> meetings = technicalUserClient.getMyMeetings();
meetingsTableModel = createTableModel(meetings);
meetingsTable = FormUIFactory.getInstance().addTableElement(getWindowControl(), "meetingsTable", meetingsTableModel, getTranslator(), flc);
meetingsTable.setEmtpyTableMessageKey("table.empty");
meetingsTable.setMultiSelect(true);
flc.contextPut("available", true);
deleteSelectedButton = FormUIFactory.getInstance().addFormLink("multiDelete", "delete.selected", "delete.selected", flc, Link.BUTTON);
return;
}
}
flc.contextPut("available", false);
}
flc.contextPut("hasMeetings", !meetings.isEmpty());
protected void doConfirmDeleteMultipleMeetings(UserRequest ureq) {
Set<Integer> selected = meetingsTable.getMultiSelectedIndex();
if (selected.size() > 0) {
String confirmMessage = MessageFormat.format(translate("confirm.multidelete.meetings"), selected.size());
dialogBox = activateYesNoDialog(ureq, translate("confirm.multidelete.meetings.title"), confirmMessage, dialogBox);
dialogBox.setUserObject(selected);
}
}
protected void doConfirmDeleteMeeting(UserRequest ureq, MeetingTableRow meetingTableRow) {
@@ -81,7 +81,8 @@ protected void initForm(@UnderInitialization SwitchInteractSystemAdminController
textPassword = uifactory.addPasswordElement("techuser_password", "switchinteract.systemadmin.techuserpassword", 32, techUserPassword, apiFlc);
String envName = (switchInteractModule == null) ? "" : NullUtil.notNullOrEmpty(switchInteractModule.getEnvName());
textEnv = uifactory.addTextElement("env_name", "switchinteract.systemadmin.envname", 100, envName, apiFlc);
textEnv.setEnabled(envName.equals("") && techUserPassword.equals("")); // name can only be set once when setting up the parameters
textEnv.setEnabled(techUserLogin.equals("") && techUserPassword.equals("")); // name can only be set once when setting up the parameters
uifactory.addStaticTextElement("", translate("environment.change.warning"), apiFlc);
submit = uifactory.addFormSubmitButton("save", apiFlc);
FormLayoutContainer cleanupFlc = FormLayoutContainer.createDefaultFormLayout("flc_cleanup", getTranslator());
@@ -41,7 +41,7 @@ public SwitchInteractFrenchTranslation(String courseNodeName) {
new String[]{"help", "Aide"},
new String[]{"help.button", "Aide"},
new String[]{"joined", "A rejoint"},
new String[]{"large.meeting.warning", "<div class=\"o_note\"><strong>Important:<strong><br/><br/>Si vous planifiez un meeting SWITCHinteract avec <strong>plus de 50 participants</strong>, veuillez en informer SWITCH par e-mail à l'adresse <a href=\"mailto:interact-support@switch.ch?cc=support@olat.uzh.ch&subject=SWITCHinteract>50\">interact-support@switch.ch</a>!</div>"},
new String[]{"large.meeting.warning", "<div class=\"o_note\"><strong>Important:</strong><br/><br/>Si vous planifiez un meeting SWITCHinteract avec <strong>plus de 50 participants</strong>, veuillez en informer SWITCH par e-mail à l'adresse <a href=\"mailto:interact-support@switch.ch?cc=support@olat.uzh.ch&subject=SWITCHinteract>50\">interact-support@switch.ch</a>!</div>"},
new String[]{"login.to.switch", "Se connecter à SWITCHinteract"},
new String[]{"meeting.date_begin", "Début"},
new String[]{"meeting.date_end", "Fin"},
@@ -41,7 +41,7 @@ public SwitchInteractItalianTranslation(String courseNodeName) {
new String[]{"help", "Guida"},
new String[]{"help.button", "Guida"},
new String[]{"joined", "Aderito"},
new String[]{"large.meeting.warning", "<div class=\"o_note\"><strong>Importante:<strong><br/><br/>Se programma un incontro SWITCHinteract con <strong>oltre 50 partecipanti</strong>, la preghiamo di informarne SWITCH per e-mail scrivendo a: <a href=\"mailto:interact-support@switch.ch?cc=support@olat.uzh.ch&subject=SWITCHinteract>50\">interact-support@switch.ch</a>!</div>"},
new String[]{"large.meeting.warning", "<div class=\"o_note\"><strong>Importante:</strong><br/><br/>Se programma un incontro SWITCHinteract con <strong>oltre 50 partecipanti</strong>, la preghiamo di informarne SWITCH per e-mail scrivendo a: <a href=\"mailto:interact-support@switch.ch?cc=support@olat.uzh.ch&subject=SWITCHinteract>50\">interact-support@switch.ch</a>!</div>"},
new String[]{"login.to.switch", "Effettuare il login in SWITCHinteract"},
new String[]{"meeting.date_begin", "Inizio"},
new String[]{"meeting.date_end", "Fine"},
@@ -1,5 +1,10 @@
<p>$r.translate("cleanup-meetings-list")</p>
<div class="container-meetings" style="padding-bottom: 20px;">
$r.render("meetingsTable")
</div>
#if ($available)
<p>$r.translate("cleanup-meetings-list")</p>
<div class="container-meetings" style="padding-bottom: 20px;">
$r.render("meetingsTable")
$r.render("multiDelete")
</div>
#else
<p>&nbsp;</p>
<p>$r.translate("switchinteract.systemadmin.misconfigured")</p>
#end
Oops, something went wrong.

0 comments on commit 23abe4e

Please sign in to comment.