diff --git a/src/main/java/org/olat/admin/user/course/CourseLeaveDialogBoxController.java b/src/main/java/org/olat/admin/user/course/CourseLeaveDialogBoxController.java index 3652566f02ab0c0df6d1ea18f9bf875ff155177e..99e7e5d1771024622eacbfe970d2ea5375a9f38e 100644 --- a/src/main/java/org/olat/admin/user/course/CourseLeaveDialogBoxController.java +++ b/src/main/java/org/olat/admin/user/course/CourseLeaveDialogBoxController.java @@ -34,6 +34,7 @@ import org.olat.core.id.Identity; import org.olat.group.BusinessGroup; import org.olat.repository.RepositoryEntry; import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -53,6 +54,9 @@ public class CourseLeaveDialogBoxController extends FormBasicController { private final List<BusinessGroup> groupsToLeave; private final List<BusinessGroup> groupsToDelete; + @Autowired + private UserManager userManager; + public CourseLeaveDialogBoxController(UserRequest ureq, WindowControl wControl, Identity leavingIdentity, List<RepositoryEntry> repoEntries, List<BusinessGroup> groupsToLeave, List<BusinessGroup> groupsToDelete) { super(ureq, wControl); @@ -77,7 +81,7 @@ public class CourseLeaveDialogBoxController extends FormBasicController { repoEntryToLeaveNames.append(entry.getDisplayname()); } - String identityName = UserManager.getInstance().getUserDisplayName(leavingIdentity); + String identityName = userManager.getUserDisplayName(leavingIdentity); String leaveText; if(groupsToLeave.isEmpty()) { leaveText = translate("unsubscribe.text", new String[]{identityName, repoEntryToLeaveNames.toString()}); diff --git a/src/main/java/org/olat/admin/user/course/CourseOverviewController.java b/src/main/java/org/olat/admin/user/course/CourseOverviewController.java index a7ff2e48f3a9f6d4727438dc4ba6eac771a856ff..eae4081ea690f2277d4bbd4d4cd3f797f697213b 100644 --- a/src/main/java/org/olat/admin/user/course/CourseOverviewController.java +++ b/src/main/java/org/olat/admin/user/course/CourseOverviewController.java @@ -233,14 +233,14 @@ public class CourseOverviewController extends BasicController { } //add the roles - if(!memberView.getMembership().isRepoOwner()) { - memberView.getMembership().setRepoOwner(membership.isOwner()); + if(!memberView.getMembership().isRepositoryEntryOwner()) { + memberView.getMembership().setRepositoryEntryOwner(membership.isOwner()); } - if(!memberView.getMembership().isRepoTutor()) { - memberView.getMembership().setRepoTutor(membership.isCoach()); + if(!memberView.getMembership().isRepositoryEntryCoach()) { + memberView.getMembership().setRepositoryEntryCoach(membership.isCoach()); } - if(!memberView.getMembership().isRepoParticipant()) { - memberView.getMembership().setRepoParticipant(membership.isParticipant()); + if(!memberView.getMembership().isRepositoryEntryParticipant()) { + memberView.getMembership().setRepositoryEntryParticipant(membership.isParticipant()); } } @@ -279,9 +279,9 @@ public class CourseOverviewController extends BasicController { memberView.setLastTime(membership.getLastModified()); } switch(membership.getMembership()) { - case owner: memberView.getMembership().setGroupTutor(true); break; - case participant: memberView.getMembership().setGroupParticipant(true); break; - case waiting: memberView.getMembership().setGroupWaiting(true); break; + case owner: memberView.getMembership().setBusinessGroupCoach(true); break; + case participant: memberView.getMembership().setBusinessGroupParticipant(true); break; + case waiting: memberView.getMembership().setBusinessGroupWaiting(true); break; } } } @@ -514,7 +514,7 @@ public class CourseOverviewController extends BasicController { RepositoryEntry re = repositoryManager.lookupRepositoryEntry(view.getRepoKey()); if(!RepositoryEntryManagedFlag.isManaged(re, RepositoryEntryManagedFlag.membersmanagement)) { repoEntryToLeave.add(re); - if(view.getMembership().isRepoOwner()) { + if(view.getMembership().isRepositoryEntryOwner()) { int numOfOwners = repositoryService.countMembers(re, GroupRoles.owner.name()); if(numOfOwners == 1) { showError("error.atleastone", view.getDisplayName()); @@ -589,7 +589,7 @@ public class CourseOverviewController extends BasicController { for(CourseMemberView view:tableDataModel.getObjects()) { if(repoEntry.getKey().equals(view.getRepoKey())) { CourseMembership membership = view.getMembership(); - return membership.isRepoOwner() || membership.isRepoTutor() || membership.isRepoParticipant(); + return membership.isRepositoryEntryOwner() || membership.isRepositoryEntryCoach() || membership.isRepositoryEntryParticipant(); } } return false; @@ -758,7 +758,7 @@ public class CourseOverviewController extends BasicController { public boolean isFullyManaged() { if(membership != null && !membership.isManagedMembersRepo() && - (membership.isRepoOwner() || membership.isRepoTutor() || membership.isRepoParticipant())) { + (membership.isRepositoryEntryOwner() || membership.isRepositoryEntryCoach() || membership.isRepositoryEntryParticipant())) { return false; } @@ -769,6 +769,8 @@ public class CourseOverviewController extends BasicController { } } } + + return true; } } @@ -780,27 +782,27 @@ public class CourseOverviewController extends BasicController { CourseMemberView membership = (CourseMemberView)val; boolean and = false; - if(membership.getMembership().isRepoOwner()) { + if(membership.getMembership().isRepositoryEntryOwner()) { and = and(sb, and); sb.append(translate("role.repo.owner")); } - if(membership.getMembership().isRepoTutor()) { + if(membership.getMembership().isRepositoryEntryCoach()) { and = and(sb, and); sb.append(translate("role.repo.tutor")); } - if(membership.getMembership().isRepoParticipant()) { + if(membership.getMembership().isRepositoryEntryParticipant()) { and = and(sb, and); sb.append(translate("role.repo.participant")); } - if(membership.getMembership().isGroupTutor()) { + if(membership.getMembership().isBusinessGroupCoach()) { and = and(sb, and); sb.append(translate("role.group.tutor")); } - if(membership.getMembership().isGroupParticipant()) { + if(membership.getMembership().isBusinessGroupParticipant()) { and = and(sb, and); sb.append(translate("role.group.participant")); } - if(membership.getMembership().isGroupWaiting()) { + if(membership.getMembership().isBusinessGroupWaiting()) { and = and(sb, and); sb.append(translate("role.group.waiting")); } diff --git a/src/main/java/org/olat/basesecurity/OrganisationRoles.java b/src/main/java/org/olat/basesecurity/OrganisationRoles.java index cd893cf75cdf5a8eb15e82b8f11a7e79b97f3db2..893faf08dce7cc05e68389cdd97c17659afa97f0 100644 --- a/src/main/java/org/olat/basesecurity/OrganisationRoles.java +++ b/src/main/java/org/olat/basesecurity/OrganisationRoles.java @@ -36,6 +36,7 @@ public enum OrganisationRoles { groupmanager, poolmanager, curriculummanager, + principal, author, coach, user, @@ -71,6 +72,7 @@ public enum OrganisationRoles { groupmanager, poolmanager, curriculummanager, + principal, author, user, }; diff --git a/src/main/java/org/olat/basesecurity/OrganisationService.java b/src/main/java/org/olat/basesecurity/OrganisationService.java index 8057ea50f5d963a8153c1ce66b3398483c0df3b7..b7544495c1eae77e77241b3b558937de1f964d71 100644 --- a/src/main/java/org/olat/basesecurity/OrganisationService.java +++ b/src/main/java/org/olat/basesecurity/OrganisationService.java @@ -182,6 +182,8 @@ public interface OrganisationService { public void setAsGuest(Identity identity); public List<OrganisationMember> getMembers(Organisation organisation); + + public List<Identity> getMembersIdentity(Organisation organisation, OrganisationRoles role); /** diff --git a/src/main/java/org/olat/basesecurity/manager/OrganisationDAO.java b/src/main/java/org/olat/basesecurity/manager/OrganisationDAO.java index afe789d65c0b25345fd52f054ccc4f0386c62f3a..0df54387447970281eb78612f7b3e1df6c09ad7c 100644 --- a/src/main/java/org/olat/basesecurity/manager/OrganisationDAO.java +++ b/src/main/java/org/olat/basesecurity/manager/OrganisationDAO.java @@ -196,6 +196,21 @@ public class OrganisationDAO { return members; } + public List<Identity> getMembersIdentity(OrganisationRef organisation, String role) { + StringBuilder sb = new StringBuilder(256); + sb.append("select ident from organisation org") + .append(" inner join org.group baseGroup") + .append(" inner join baseGroup.members membership") + .append(" inner join membership.identity ident") + .append(" inner join fetch ident.user identUser") + .append(" where org.key=:organisationKey and membership.role=:role"); + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Identity.class) + .setParameter("organisationKey", organisation.getKey()) + .setParameter("role", role) + .getResultList(); + } + public List<Identity> getIdentities(String organisationIdentifier, String role) { StringBuilder sb = new StringBuilder(256); sb.append("select ident from organisation org") diff --git a/src/main/java/org/olat/basesecurity/manager/OrganisationServiceImpl.java b/src/main/java/org/olat/basesecurity/manager/OrganisationServiceImpl.java index e733d885178d34e802d1497ffad7c6997a1a590e..0f408ba86bce1fdfbee00974669f7a085fa4d635 100644 --- a/src/main/java/org/olat/basesecurity/manager/OrganisationServiceImpl.java +++ b/src/main/java/org/olat/basesecurity/manager/OrganisationServiceImpl.java @@ -334,6 +334,11 @@ public class OrganisationServiceImpl implements OrganisationService, Initializin return organisationDao.getMembers(organisation); } + @Override + public List<Identity> getMembersIdentity(Organisation organisation, OrganisationRoles role) { + return organisationDao.getMembersIdentity(organisation, role.name()); + } + @Override public void setAsGuest(Identity identity) { OrganisationImpl defOrganisation = (OrganisationImpl)getDefaultOrganisation(); diff --git a/src/main/java/org/olat/commons/memberlist/ui/MembersListDisplayRunController.java b/src/main/java/org/olat/commons/memberlist/ui/MembersListDisplayRunController.java index 323d00ea71dfabfae3896470b0ebbc73c540bb5f..74489f52fe09238b8b0d18135f5a281da1ced331 100644 --- a/src/main/java/org/olat/commons/memberlist/ui/MembersListDisplayRunController.java +++ b/src/main/java/org/olat/commons/memberlist/ui/MembersListDisplayRunController.java @@ -61,7 +61,7 @@ import org.olat.course.run.environment.CourseEnvironment; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupMembership; import org.olat.group.ui.main.MemberListTableModel; -import org.olat.group.ui.main.MemberView; +import org.olat.group.ui.main.MemberRow; import org.olat.modules.co.ContactFormController; import org.olat.repository.RepositoryEntry; import org.olat.user.DisplayPortraitManager; @@ -183,7 +183,7 @@ public class MembersListDisplayRunController extends BasicController { Collections.sort(waiting, idComparator); waitingtList = convertIdentitiesToMembers(waiting); - Set<MemberView> duplicateCatcher = new HashSet<>(); + Set<MemberRow> duplicateCatcher = new HashSet<>(); boolean userLastTimeVisible = cacheGroupMemberships(ureq); if (showOwners && !owners.isEmpty()) { diff --git a/src/main/java/org/olat/commons/memberlist/ui/MembersTableController.java b/src/main/java/org/olat/commons/memberlist/ui/MembersTableController.java index 35cc968b715fde425ed8f31ae489bd0451408585..c4a7bc314e3326cac3f9ebf3668520d37cf58267 100644 --- a/src/main/java/org/olat/commons/memberlist/ui/MembersTableController.java +++ b/src/main/java/org/olat/commons/memberlist/ui/MembersTableController.java @@ -61,10 +61,11 @@ import org.olat.core.util.mail.ContactMessage; import org.olat.course.run.environment.CourseEnvironment; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupMembership; +import org.olat.group.model.MemberView; import org.olat.group.ui.main.AbstractMemberListController; import org.olat.group.ui.main.MemberListTableModel; import org.olat.group.ui.main.MemberListTableModel.Cols; -import org.olat.group.ui.main.MemberView; +import org.olat.group.ui.main.MemberRow; import org.olat.instantMessaging.InstantMessagingModule; import org.olat.instantMessaging.InstantMessagingService; import org.olat.instantMessaging.OpenInstantMessageEvent; @@ -93,9 +94,9 @@ public class MembersTableController extends FormBasicController { private final boolean chatEnabled, canEmail, deduplicateList, editable, userLastTimeVisible; private final List<UserPropertyHandler> userPropertyHandlers; - private final List<MemberView> membersList; + private final List<MemberRow> membersList; private final RepositoryEntry repoEntry; - private Set<MemberView> duplicateCatcher; + private Set<MemberRow> duplicateCatcher; @Autowired private UserManager userManager; @@ -111,7 +112,7 @@ public class MembersTableController extends FormBasicController { private int pageSize = 20; - public MembersTableController(UserRequest ureq, WindowControl wControl, List<Identity> members, Set<MemberView> duplicateCatcher, Map<Long,Date> recentLaunches, Map<Long,Date> initialLaunches, + public MembersTableController(UserRequest ureq, WindowControl wControl, List<Identity> members, Set<MemberRow> duplicateCatcher, Map<Long,Date> recentLaunches, Map<Long,Date> initialLaunches, List<UserPropertyHandler> userPropertyHandlers, Map<Long,BusinessGroupMembership> groupmemberships, RepositoryEntry repoEntry, BusinessGroup businessGroup, CourseEnvironment courseEnv, boolean deduplicateList, Translator translator, boolean editable, boolean canEmail, boolean userLastTimeVisible) { super(ureq, wControl, "table"); @@ -130,7 +131,7 @@ public class MembersTableController extends FormBasicController { this.businessGroup = businessGroup; this.courseEnv = courseEnv; - this.membersList = getMembersFromIdentity(ureq, members, groupmemberships, recentLaunches, initialLaunches); + membersList = getMembersFromIdentity(members, groupmemberships, recentLaunches, initialLaunches); initForm(ureq); } @@ -162,17 +163,17 @@ public class MembersTableController extends FormBasicController { SelectionEvent se = (SelectionEvent)event; String cmd = se.getCommand(); if ("vcard".equals(cmd)) { - MemberView row = membersModel.getObject(se.getIndex()); + MemberRow row = membersModel.getObject(se.getIndex()); doOpenHomePage(row, ureq); } else if ("email".equals(cmd)) { - MemberView row = membersModel.getObject(se.getIndex()); + MemberRow row = membersModel.getObject(se.getIndex()); doSendEmailToMember(row, ureq); } } } else if (source instanceof FormLink) { FormLink link = (FormLink)source; String cmd = link.getCmd(); - MemberView row = (MemberView)link.getUserObject(); + MemberRow row = (MemberRow)link.getUserObject(); if ("im".equals(cmd)) { doOpenChat(row, ureq); } @@ -208,14 +209,14 @@ public class MembersTableController extends FormBasicController { // } - private List<MemberView> getMembersFromIdentity(UserRequest ureq, List<Identity> identities, + private List<MemberRow> getMembersFromIdentity(List<Identity> identities, Map<Long,BusinessGroupMembership> groupmemberships, Map<Long,Date> recentLaunches, Map<Long,Date> initialLaunches) { if (!deduplicateList) { duplicateCatcher = new HashSet<>(); } - List<MemberView> memberList = new ArrayList<>(); + List<MemberRow> memberList = new ArrayList<>(); for (Identity identity : identities) { - MemberView member = new MemberView(identity, userPropertyHandlers, getLocale()); + MemberRow member = new MemberRow(new MemberView(identity, userPropertyHandlers, getLocale())); if (userLastTimeVisible) { if (repoEntry == null) { BusinessGroupMembership groupmembership = groupmemberships.get(identity.getKey()); @@ -230,7 +231,7 @@ public class MembersTableController extends FormBasicController { } if (!duplicateCatcher.contains(member)) { memberList.add(member); - if (!identity.equals(ureq.getIdentity())){ + if (!identity.equals(getIdentity())){ forgeChatLink(member); } } @@ -239,7 +240,7 @@ public class MembersTableController extends FormBasicController { return memberList; } - protected void forgeChatLink(MemberView row) { + protected void forgeChatLink(MemberRow row) { FormLink chatLink = uifactory.addFormLink("tools_" + counter.incrementAndGet(), "im", "", null, null, Link.NONTRANSLATED); chatLink.setIconLeftCSS("o_icon o_icon_status_unavailable"); chatLink.setUserObject(row); @@ -289,7 +290,7 @@ public class MembersTableController extends FormBasicController { return defaultSortKey; } - private void doSendEmailToMember(MemberView member, UserRequest ureq) { + private void doSendEmailToMember(MemberRow member, UserRequest ureq) { if (!editable) return; ContactList memberList; Identity identity = securityManager.loadIdentityByKey(member.getIdentityKey()); @@ -341,14 +342,14 @@ public class MembersTableController extends FormBasicController { } } - private void doOpenHomePage(MemberView member, UserRequest ureq) { + private void doOpenHomePage(MemberRow member, UserRequest ureq) { String url = "[HomePage:" + member.getIdentityKey() + "]"; BusinessControl bc = BusinessControlFactory.getInstance().createFromString(url); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); NewControllerFactory.getInstance().launch(ureq, bwControl); } - private void doOpenChat(MemberView member, UserRequest ureq) { + private void doOpenChat(MemberRow member, UserRequest ureq) { Buddy buddy = imService.getBuddyById(member.getIdentityKey()); OpenInstantMessageEvent e = new OpenInstantMessageEvent(ureq, buddy); ureq.getUserSession().getSingleUserEventCenter().fireEventToListenersOf(e, InstantMessagingService.TOWER_EVENT_ORES); diff --git a/src/main/java/org/olat/course/member/MemberListController.java b/src/main/java/org/olat/course/member/MemberListController.java index 710220607adff25d03c1f7763b11b98077f4b469..c9a2f2d2d36e29b35c2c69711eb69c897620ed1d 100644 --- a/src/main/java/org/olat/course/member/MemberListController.java +++ b/src/main/java/org/olat/course/member/MemberListController.java @@ -27,7 +27,7 @@ import org.olat.core.util.StringHelper; import org.olat.course.assessment.ui.tool.AssessmentIdentityCourseController; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.ui.main.AbstractMemberListController; -import org.olat.group.ui.main.MemberView; +import org.olat.group.ui.main.MemberRow; import org.olat.group.ui.main.SearchMembersParams; import org.olat.repository.RepositoryEntry; @@ -54,7 +54,7 @@ public class MemberListController extends AbstractMemberListController { } @Override - protected void doOpenAssessmentTool(UserRequest ureq, MemberView member) { + protected void doOpenAssessmentTool(UserRequest ureq, MemberRow member) { removeAsListenerAndDispose(identityAssessmentController); Identity assessedIdentity = securityManager.loadIdentityByKey(member.getIdentityKey()); diff --git a/src/main/java/org/olat/course/member/MemberListWithOriginFilterController.java b/src/main/java/org/olat/course/member/MemberListWithOriginFilterController.java index feeede75a1781d0515bb96ea60b549d053613b7e..6c0bb08ae71e32e1d4467b9f5f6ec9e9fcd76126 100644 --- a/src/main/java/org/olat/course/member/MemberListWithOriginFilterController.java +++ b/src/main/java/org/olat/course/member/MemberListWithOriginFilterController.java @@ -32,8 +32,9 @@ import org.olat.core.util.StringHelper; import org.olat.course.assessment.ui.tool.AssessmentIdentityCourseController; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.ui.main.AbstractMemberListController; -import org.olat.group.ui.main.MemberView; +import org.olat.group.ui.main.MemberRow; import org.olat.group.ui.main.SearchMembersParams; +import org.olat.group.ui.main.SearchMembersParams.Origin; import org.olat.repository.RepositoryEntry; /** @@ -42,7 +43,7 @@ import org.olat.repository.RepositoryEntry; */ public class MemberListWithOriginFilterController extends AbstractMemberListController { - private static final String[] originKeys = new String[]{"all", "repo", "group"}; + private static final String[] originKeys = new String[]{ Origin.all.name(), Origin.repositoryEntry.name(), Origin.businessGroup.name(), Origin.curriculum.name()}; private SingleSelection originEl; @@ -78,15 +79,10 @@ public class MemberListWithOriginFilterController extends AbstractMemberListCont @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(originEl == source) { - if(!originEl.isOneSelected() || originEl.isSelected(0)) { - searchParams.setRepoOrigin(true); - searchParams.setGroupOrigin(true); - } else if(originEl.isSelected(1)) { - searchParams.setRepoOrigin(true); - searchParams.setGroupOrigin(false); - } else if(originEl.isSelected(2)) { - searchParams.setRepoOrigin(false); - searchParams.setGroupOrigin(true); + if(!originEl.isOneSelected()) { + searchParams.setOrigin(Origin.all); + } else { + searchParams.setOrigin(Origin.valueOf(originEl.getSelectedKey())); } membersTable.deselectAll(); reloadModel(); @@ -96,7 +92,7 @@ public class MemberListWithOriginFilterController extends AbstractMemberListCont } @Override - protected void doOpenAssessmentTool(UserRequest ureq, MemberView member) { + protected void doOpenAssessmentTool(UserRequest ureq, MemberRow member) { removeAsListenerAndDispose(identityAssessmentController); Identity assessedIdentity = securityManager.loadIdentityByKey(member.getIdentityKey()); diff --git a/src/main/java/org/olat/course/member/MemberSearchController.java b/src/main/java/org/olat/course/member/MemberSearchController.java index cf331a0b52aa127eb8de85a57d58f0b1bccac7df..1961cac53964906b470d9743dad4f468e363ae2b 100644 --- a/src/main/java/org/olat/course/member/MemberSearchController.java +++ b/src/main/java/org/olat/course/member/MemberSearchController.java @@ -29,7 +29,7 @@ import org.olat.core.id.Identity; import org.olat.course.assessment.ui.tool.AssessmentIdentityCourseController; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.ui.main.AbstractMemberListController; -import org.olat.group.ui.main.MemberView; +import org.olat.group.ui.main.MemberRow; import org.olat.group.ui.main.SearchMembersParams; import org.olat.repository.RepositoryEntry; @@ -80,7 +80,7 @@ public class MemberSearchController extends AbstractMemberListController { } @Override - protected void doOpenAssessmentTool(UserRequest ureq, MemberView member) { + protected void doOpenAssessmentTool(UserRequest ureq, MemberRow member) { removeAsListenerAndDispose(identityAssessmentController); Identity assessedIdentity = securityManager.loadIdentityByKey(member.getIdentityKey()); diff --git a/src/main/java/org/olat/course/member/MemberSearchForm.java b/src/main/java/org/olat/course/member/MemberSearchForm.java index 4742da57dab868c4d755b22b1ab224692f3d1a47..74e4a933956c31ce663295f9014dfd47a908eddf 100644 --- a/src/main/java/org/olat/course/member/MemberSearchForm.java +++ b/src/main/java/org/olat/course/member/MemberSearchForm.java @@ -19,12 +19,13 @@ */ package org.olat.course.member; -import java.util.Collection; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.olat.basesecurity.GroupRoles; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -43,6 +44,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.util.StringHelper; import org.olat.core.util.Util; import org.olat.group.ui.main.SearchMembersParams; +import org.olat.group.ui.main.SearchMembersParams.Origin; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.EmailProperty; import org.olat.user.propertyhandlers.UserPropertyHandler; @@ -54,8 +56,8 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class MemberSearchForm extends FormBasicController implements ExtendedFlexiTableSearchController { - private String[] roleKeys = {"owner", "tutor", "attendee", "waiting"}; - private String[] originKeys = new String[]{"all", "repo", "group"}; + private String[] roleKeys = { GroupRoles.owner.name(), GroupRoles.coach.name(), GroupRoles.participant.name(), GroupRoles.waiting.name() }; + private String[] originKeys = new String[]{ Origin.all.name(), Origin.repositoryEntry.name(), Origin.businessGroup.name(), Origin.curriculum.name() }; private TextElement login; private SingleSelection originEl; @@ -124,7 +126,7 @@ public class MemberSearchForm extends FormBasicController implements ExtendedFle for(int i=originKeys.length; i-->0; ) { openValues[i] = translate("search." + originKeys[i]); } - originEl = uifactory.addRadiosHorizontal("openBg", "search.origin", rightContainer, originKeys, openValues); + originEl = uifactory.addRadiosVertical("openBg", "search.origin", rightContainer, originKeys, openValues); originEl.select("all", true); FormLayoutContainer buttonLayout = FormLayoutContainer.createDefaultFormLayout("button_layout", getTranslator()); @@ -167,24 +169,19 @@ public class MemberSearchForm extends FormBasicController implements ExtendedFle private void fireSearchEvent(UserRequest ureq) { SearchMembersParams params = new SearchMembersParams(); //roles - Collection<String> selectedKeys = rolesEl.getSelectedKeys(); - params.setRepoOwners(selectedKeys.contains("owner")); - params.setRepoTutors(selectedKeys.contains("tutor")); - params.setGroupTutors(selectedKeys.contains("tutor")); - params.setRepoParticipants(selectedKeys.contains("attendee")); - params.setGroupParticipants(selectedKeys.contains("attendee")); - params.setGroupWaitingList(selectedKeys.contains("waiting")); + List<String> selectedKeys = new ArrayList<>(rolesEl.getSelectedKeys()); + GroupRoles[] roles = new GroupRoles[selectedKeys.size()]; + for(int i=0; i<selectedKeys.size(); i++) { + roles[i] = GroupRoles.valueOf(selectedKeys.get(i)); + } + + params.setRoles(roles); //origin - if(!originEl.isOneSelected() || originEl.isSelected(0)) { - params.setRepoOrigin(true); - params.setGroupOrigin(true); - } else if(originEl.isSelected(1)) { - params.setRepoOrigin(true); - params.setGroupOrigin(false); - } else if(originEl.isSelected(2)) { - params.setRepoOrigin(false); - params.setGroupOrigin(true); + if(!originEl.isOneSelected()) { + params.setOrigin(Origin.all); + } else { + params.setOrigin(Origin.valueOf(originEl.getSelectedKey())); } String loginVal = login.getValue(); diff --git a/src/main/java/org/olat/course/member/MembersManagementMainController.java b/src/main/java/org/olat/course/member/MembersManagementMainController.java index 976e2de8558cecabaa23831b16475dbc5e27e7f5..610d9e1c8f04170df8bc512741944959a44718b2 100644 --- a/src/main/java/org/olat/course/member/MembersManagementMainController.java +++ b/src/main/java/org/olat/course/member/MembersManagementMainController.java @@ -63,7 +63,7 @@ import org.springframework.beans.factory.annotation.Autowired; * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class MembersManagementMainController extends MainLayoutBasicController implements Activateable2 { +public class MembersManagementMainController extends MainLayoutBasicController implements Activateable2 { private static final String CMD_MEMBERS = "Members"; private static final String CMD_GROUPS = "Groups"; diff --git a/src/main/java/org/olat/course/member/MembersOverviewController.java b/src/main/java/org/olat/course/member/MembersOverviewController.java index cf1893e23974b252aa0129dac934bf3a205598da..849f2896d07f31bf163b25b18894b1032e25e9c0 100644 --- a/src/main/java/org/olat/course/member/MembersOverviewController.java +++ b/src/main/java/org/olat/course/member/MembersOverviewController.java @@ -21,6 +21,7 @@ package org.olat.course.member; import java.util.List; +import org.olat.basesecurity.GroupRoles; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; @@ -432,7 +433,7 @@ public class MembersOverviewController extends BasicController implements Activa OLATResourceable ores = OresHelper.createOLATResourceableInstance(SEG_ALL_MEMBERS, 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); - SearchMembersParams searchParams = new SearchMembersParams(true, true, true, true, true, false, true); + SearchMembersParams searchParams = new SearchMembersParams(true, GroupRoles.owner, GroupRoles.coach, GroupRoles.participant); allMemberListCtrl = new MemberListWithOriginFilterController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, searchParams, null); listenTo(allMemberListCtrl); } @@ -449,7 +450,7 @@ public class MembersOverviewController extends BasicController implements Activa OLATResourceable ores = OresHelper.createOLATResourceableInstance(SEG_OWNERS_MEMBERS, 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); - SearchMembersParams searchParams = new SearchMembersParams(true, false, false, false, false, false, false); + SearchMembersParams searchParams = new SearchMembersParams(false, GroupRoles.owner); String infos = translate("owners.infos"); ownersCtrl = new MemberListController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, searchParams, infos); listenTo(ownersCtrl); @@ -467,7 +468,7 @@ public class MembersOverviewController extends BasicController implements Activa OLATResourceable ores = OresHelper.createOLATResourceableInstance(SEG_TUTORS_MEMBERS, 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); - SearchMembersParams searchParams = new SearchMembersParams(false, true, false, true, false, false, false); + SearchMembersParams searchParams = new SearchMembersParams(false, GroupRoles.coach); String infos = translate("tutors.infos"); tutorsCtrl = new MemberListWithOriginFilterController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, searchParams, infos); listenTo(tutorsCtrl); @@ -485,7 +486,7 @@ public class MembersOverviewController extends BasicController implements Activa OLATResourceable ores = OresHelper.createOLATResourceableInstance(SEG_PARTICIPANTS_MEMBERS, 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); - SearchMembersParams searchParams = new SearchMembersParams(false, false, true, false, true, false, true); + SearchMembersParams searchParams = new SearchMembersParams(false, GroupRoles.participant); String infos = translate("participants.infos"); participantsCtrl = new MemberListWithOriginFilterController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, searchParams, infos); listenTo(participantsCtrl); @@ -503,7 +504,7 @@ public class MembersOverviewController extends BasicController implements Activa OLATResourceable ores = OresHelper.createOLATResourceableInstance(SEG_WAITING_MEMBERS, 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); - SearchMembersParams searchParams = new SearchMembersParams(false, false, false, false, false, true, false); + SearchMembersParams searchParams = new SearchMembersParams(false, GroupRoles.waiting); String infos = translate("waiting.infos"); waitingCtrl = new MemberListController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, searchParams, infos); listenTo(waitingCtrl); diff --git a/src/main/java/org/olat/course/member/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/member/_i18n/LocalStrings_de.properties index 51db894e8a0f3abb01b80da298e92f3df0700777..7b13e1fff8cc18e4709ed69d6e8b6f191ee0c0a4 100644 --- a/src/main/java/org/olat/course/member/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/member/_i18n/LocalStrings_de.properties @@ -19,7 +19,6 @@ error.atleastone=$org.olat.group.ui.main\:error.atleastone error.msg.send.no.rcps=$org.olat.modules.co\:error.msg.send.no.rcps error.select.one=$org.olat.group.ui.main\:error.select.one error.managed.group=$org.olat.group.ui.main\:error.managed.group - group.add=Gruppe hinzuf\u00FCgen group.create=Gruppe erstellen group.remove=$org.olat.group.ui.edit\:resource.remove @@ -51,13 +50,14 @@ role.repo.participant=Teilnehmer role.repo.tutor=Betreuer search=Suche search.all=alle Mitglieder -search.attendee=$\:role.repo.participant -search.group=nur Gruppenmitglieder +search.participant=$\:role.repo.participant +search.curriculum=nur Curriculummitglieder +search.businessGroup=nur Gruppenmitglieder search.login=Benutzername search.origin=Herkunft search.origin.alt=Anzeige search.owner=$\:role.repo.owner -search.repo=nur Kursmitglieder +search.repositoryEntry=nur Kursmitglieder search.roles=Rolle search.tutor=$\:role.repo.tutor search.waiting=$\:role.group.waiting diff --git a/src/main/java/org/olat/course/member/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/member/_i18n/LocalStrings_en.properties index c9687cb218557a63434ea4d7160fb3a2508de8fc..72415fd1a30d2f2b770624e6bec04686ee1d1f0f 100644 --- a/src/main/java/org/olat/course/member/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/member/_i18n/LocalStrings_en.properties @@ -50,15 +50,16 @@ role.repo.participant=Participant role.repo.tutor=Coach search=Search search.all=all members -search.attendee=$\:role.repo.participant -search.group=only group members +search.participant=$\:role.repo.participant +search.curriculum=only curriculum members +search.businessGroup=only group members search.login=User name search.origin=Origin search.origin.alt=Show search.owner=$\:role.repo.owner -search.repo=only course members +search.repositoryEntry=only course members search.roles=Role -search.tutor=$\:role.repo.tutor +search.coach=$\:role.repo.tutor search.waiting=Waiting list select.group=Add group table.header.edit=Edit diff --git a/src/main/java/org/olat/course/member/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/member/_i18n/LocalStrings_fr.properties index 6f9a40e65e94fe153a40637a7a9139b4172580c4..e71800e49b18caffc5bb8db069f8a1d7b05f8490 100644 --- a/src/main/java/org/olat/course/member/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/course/member/_i18n/LocalStrings_fr.properties @@ -50,15 +50,15 @@ role.repo.participant=Participant role.repo.tutor=Coach search=Recherche search.all=tous les membres -search.attendee=$\:role.repo.participant -search.group=seulement les membres du groupe +search.participant=$\:role.repo.participant +search.businessGroup=seulement les membres du groupe search.login=Nom d'utilisateur search.origin=Origine search.origin.alt=Origine search.owner=$\:role.repo.owner -search.repo=seulement les membres du cours +search.repositoryEntry=seulement les membres du cours search.roles=R\u00F4les -search.tutor=$\:role.repo.tutor +search.coach=$\:role.repo.tutor search.waiting=$\:role.group.waiting select.group=S\u00E9lectionner des groupes table.header.edit=Editer diff --git a/src/main/java/org/olat/course/member/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/course/member/_i18n/LocalStrings_it.properties index 9aae98182299597614ccde13e2f49aed911006fe..e59aa1c75b488df0ccd1c0c75b41b4affe8a40bf 100644 --- a/src/main/java/org/olat/course/member/_i18n/LocalStrings_it.properties +++ b/src/main/java/org/olat/course/member/_i18n/LocalStrings_it.properties @@ -50,15 +50,15 @@ role.repo.participant=Partecipante role.repo.tutor=Tutore search=Ricerca search.all=tutti i membri -search.attendee=$\:role.repo.participant -search.group=solo i membri del gruppo +search.participant=$\:role.repo.participant +search.businessGroup=solo i membri del gruppo search.login=Nome utente search.origin=Origine search.origin.alt=Mostrare search.owner=$\:role.repo.owner -search.repo=solo membri del corso +search.repositoryEntry=solo membri del corso search.roles=Ruolo -search.tutor=$\:role.repo.tutor +search.coach=$\:role.repo.tutor search.waiting=$\:role.group.waiting select.group=Aggiungere gruppo table.header.edit=Modificare diff --git a/src/main/java/org/olat/course/member/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/course/member/_i18n/LocalStrings_pl.properties index 3c4968f2938f4d0d554504286f92c773d2e7dcc5..9682c60c159ffc45b19df5b50031d29564271551 100644 --- a/src/main/java/org/olat/course/member/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/course/member/_i18n/LocalStrings_pl.properties @@ -39,15 +39,15 @@ role.repo.participant=Uczestnik role.repo.tutor=Nauczyciel search=Szukaj search.all=wszyscy cz\u0142onkowie -search.attendee=$\:role.repo.participant -search.group=tylko cz\u0142onkowie grupy +search.participant=$\:role.repo.participant +search.businessGroup=tylko cz\u0142onkowie grupy search.login=Nazwa u\u017Cytkownika search.origin=Pochodzenie search.origin.alt=Poka\u017C search.owner=$\:role.repo.owner -search.repo=tylko cz\u0142onkowie kursu +search.repositoryEntry=tylko cz\u0142onkowie kursu search.roles=Rola -search.tutor=$\:role.repo.tutor +search.coach=$\:role.repo.tutor search.waiting=Lista oczekuj\u0105cych select.group=Dodaj grup\u0119 table.header.edit=Edytuj diff --git a/src/main/java/org/olat/course/member/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/member/_i18n/LocalStrings_pt_BR.properties index a9830a321788db7c14aae9006876e08e4a843deb..ad40f595da6833e1d71a2740d641be47cb2088be 100644 --- a/src/main/java/org/olat/course/member/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/course/member/_i18n/LocalStrings_pt_BR.properties @@ -50,15 +50,15 @@ role.repo.participant=Participante role.repo.tutor=Treinador search=Buscar search.all=Todos membros -search.attendee=$\:role.repo.participant -search.group=Apenas membros de grupos +search.participant=$\:role.repo.participant +search.businessGroup=Apenas membros de grupos search.login=Usu\u00E1rio search.origin=Origem search.origin.alt=Mostrar search.owner=$\:role.repo.owner -search.repo=Apenas membros de curso +search.repositoryEntry=Apenas membros de curso search.roles=Fun\u00E7\u00E3o -search.tutor=$\:role.repo.tutor +search.coach=$\:role.repo.tutor search.waiting=Lista de espera select.group=Adicionar grupo table.header.edit=Editar diff --git a/src/main/java/org/olat/course/member/_i18n/LocalStrings_zh_CN.properties b/src/main/java/org/olat/course/member/_i18n/LocalStrings_zh_CN.properties index fac086802ad4e3c24d4cda7076af26321dfd6239..0606c423885fd83890bb9c001647759afa17f4f1 100644 --- a/src/main/java/org/olat/course/member/_i18n/LocalStrings_zh_CN.properties +++ b/src/main/java/org/olat/course/member/_i18n/LocalStrings_zh_CN.properties @@ -16,15 +16,15 @@ role.repo.participant=\u53C2\u4E0E\u8005 role.repo.tutor=\u8F85\u5BFC\u5458 search=\u68C0\u7D22 search.all=\u6240\u6709\u6210\u5458 -search.attendee=$\:role.repo.participant -search.group=\u4EC5\u9650\u7FA4\u7EC4\u6210\u5458 +search.participant=$\:role.repo.participant +search.businessGroup=\u4EC5\u9650\u7FA4\u7EC4\u6210\u5458 search.login=\u7528\u6237\u540D\u79F0 search.origin=\u7C4D\u8D2F search.origin.alt=\u901A\u544A search.owner=$\:role.repo.owner -search.repo=\u4EC5\u9650\u8BFE\u7A0B\u6210\u5458 +search.repositoryEntry=\u4EC5\u9650\u8BFE\u7A0B\u6210\u5458 search.roles=\u89D2\u8272 -search.tutor=$\:role.repo.tutor +search.coach=$\:role.repo.tutor search.waiting=$\:role.group.waiting select.group=\u6DFB\u52A0\u7FA4\u7EC4 table.header.edit=\u5904\u7406 diff --git a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java index 8c2185b95cf99c07cfdeb3d9832be13db28f9ace..90911886dc37b68d415f13db22477a83f7c418d2 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java @@ -292,7 +292,7 @@ public class BusinessGroupDAO { groupKeys.add(group.getKey()); } - Map<IdentityGroupKey, BusinessGroupMembershipImpl> memberships = new HashMap<IdentityGroupKey, BusinessGroupMembershipImpl>(); + Map<IdentityGroupKey, BusinessGroupMembershipImpl> memberships = new HashMap<>(); loadBusinessGroupsMembership(groupKeys, memberships); return new ArrayList<BusinessGroupMembership>(memberships.values()); } diff --git a/src/main/java/org/olat/group/manager/MemberViewQueries.java b/src/main/java/org/olat/group/manager/MemberViewQueries.java new file mode 100644 index 0000000000000000000000000000000000000000..0b24bcc9d7e48249822e8b79154e27633cabccfc --- /dev/null +++ b/src/main/java/org/olat/group/manager/MemberViewQueries.java @@ -0,0 +1,352 @@ +/** + * <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> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.group.manager; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import javax.persistence.TypedQuery; + +import org.olat.basesecurity.GroupRoles; +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.persistence.PersistenceHelper; +import org.olat.core.id.Identity; +import org.olat.core.util.StringHelper; +import org.olat.group.BusinessGroup; +import org.olat.group.model.MemberView; +import org.olat.group.ui.main.SearchMembersParams; +import org.olat.group.ui.main.SearchMembersParams.Origin; +import org.olat.repository.RepositoryEntry; +import org.olat.user.propertyhandlers.UserPropertyHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 6 juin 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Service +public class MemberViewQueries { + + @Autowired + private DB dbInstance; + + public List<MemberView> getBusinessGroupMembers(BusinessGroup businessGroup, SearchMembersParams params, + List<UserPropertyHandler> userPropertyHandlers, Locale locale) { + if(businessGroup == null) return Collections.emptyList(); + + StringBuilder sb = new StringBuilder(); + sb.append("select membership.key, membership.role, membership.creationDate, membership.lastModified, ident") + .append(" from businessgroup as grp") + .append(" inner join grp.baseGroup as baseGroup") + .append(" inner join baseGroup.members as membership") + .append(" inner join membership.identity as ident") + .append(" inner join fetch ident.user as identUser") + .append(" where grp.key=:businessGroupKey"); + searchByIdentity(sb, params); + + TypedQuery<Object[]> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Object[].class) + .setParameter("businessGroupKey", businessGroup.getKey()); + searchByIdentity(query, params); + + List<Object[]> rawObjects = query.getResultList(); + Map<Identity,MemberView> views = new HashMap<>(); + for(Object[] objects:rawObjects) { + int pos = 1;// 0 is the membershipKey + String role = (String)objects[pos++]; + Date creationDate = (Date)objects[pos++]; + Date lastModified = (Date)objects[pos++]; + + Identity identity = (Identity)objects[pos++]; + MemberView view = views.computeIfAbsent(identity, id -> new MemberView(id, userPropertyHandlers, locale, creationDate, lastModified)); + view.addGroup(businessGroup); + view.getMemberShip().setBusinessGroupRole(role); + } + + getPending(views, businessGroup, params, userPropertyHandlers, locale); + + List<MemberView> members = new ArrayList<>(views.values()); + filterByRoles(members, params); + filterByOrigin(members, params); + return members; + } + + public List<MemberView> getRepositoryEntryMembers(RepositoryEntry entry, SearchMembersParams params, + List<UserPropertyHandler> userPropertyHandlers, Locale locale) { + if(entry == null) return Collections.emptyList(); + + Map<Identity,MemberView> views = getMembersView(entry, params, userPropertyHandlers, locale); + getPending(views, entry, params, userPropertyHandlers, locale); + + List<MemberView> members = new ArrayList<>(views.values()); + filterByRoles(members, params); + filterByOrigin(members, params); + return members; + } + + private Map<Identity,MemberView> getMembersView(RepositoryEntry entry, SearchMembersParams params, + List<UserPropertyHandler> userPropertyHandlers, Locale locale) { + StringBuilder sb = new StringBuilder(); + sb.append("select membership.key, membership.role, membership.creationDate, membership.lastModified, ident, relGroup.defaultGroup,") + .append(" grp.key, grp.name, grp.managedFlagsString,") + .append(" curriculumEl.key, curriculumEl.displayName, curriculumEl.managedFlagsString") + .append(" from repositoryentry as v ") + .append(" inner join v.groups as relGroup") + .append(" inner join relGroup.group as baseGroup") + .append(" inner join baseGroup.members as membership") + .append(" inner join membership.identity as ident") + .append(" inner join fetch ident.user as identUser") + .append(" left join businessgroup as grp on (grp.baseGroup.key=baseGroup.key)") + .append(" left join curriculumelement as curriculumEl on (curriculumEl.group.key=baseGroup.key)") + .append(" where v.key=:repoEntryKey"); + searchByIdentity(sb, params); + + TypedQuery<Object[]> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Object[].class) + .setParameter("repoEntryKey", entry.getKey()); + searchByIdentity(query, params); + + List<Object[]> rawObjects = query.getResultList(); + Map<Identity,MemberView> views = new HashMap<>(); + for(Object[] objects:rawObjects) { + int pos = 1;// 0 is the membershipKey + String role = (String)objects[pos++]; + Date creationDate = (Date)objects[pos++]; + Date lastModified = (Date)objects[pos++]; + Identity member = (Identity)objects[pos++]; + MemberView view = views.computeIfAbsent(member, id -> new MemberView(id, userPropertyHandlers, locale, creationDate, lastModified)); + + Boolean defaultGroup = (Boolean)objects[pos++]; + + Long groupKey = (Long)objects[pos++]; + String groupName = (String)objects[pos++]; + String groupManagedflags = (String)objects[pos++]; + + Long curriculumElementKey = (Long)objects[pos++]; + String curriculumElementName = (String)objects[pos++]; + String curriculumElementManagedFlags = (String)objects[pos++]; + + if(defaultGroup != null && defaultGroup.booleanValue()) { + view.setRepositoryEntryDisplayName(entry.getDisplayname()); + view.setManagedFlags(entry.getManagedFlags()); + view.getMemberShip().setRepositoryEntryRole(role); + } else if(groupKey != null) { + view.addGroup(new MemberView.BusinessGroupShortImpl(groupKey, groupName, groupManagedflags)); + view.getMemberShip().setBusinessGroupRole(role); + } else if(curriculumElementKey != null) { + view.addCurriculumElement(new MemberView.CurriculumElementShortImpl(curriculumElementKey, curriculumElementName, curriculumElementManagedFlags)); + view.getMemberShip().setCurriculumElementRole(role); + } + } + return views; + } + + private void getPending(Map<Identity,MemberView> views, RepositoryEntry entry, SearchMembersParams params, + List<UserPropertyHandler> userPropertyHandlers, Locale locale) { + StringBuilder sb = new StringBuilder(); + sb.append("select ident from resourcereservation as reservation") + .append(" inner join reservation.identity as ident") + .append(" inner join fetch ident.user as identUser") + .append(" where reservation.resource.key in (select v.olatResource.key from repositoryentry as v where v.key=:repoEntryKey)") + .append(" or reservation.resource.key in (select grp.resource.key from businessgroup as grp") + .append(" inner join repoentrytogroup as rel on (grp.baseGroup.key=rel.group.key)") + .append(" where rel.entry.key=:repoEntryKey") + .append(" )"); + searchByIdentity(sb, params); + + TypedQuery<Identity> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Identity.class) + .setParameter("repoEntryKey", entry.getKey()); + searchByIdentity(query, params); + + List<Identity> identities = query.getResultList(); + for(Identity identity:identities) { + views.computeIfAbsent(identity, id -> new MemberView(id, userPropertyHandlers, locale)).setPending(true); + } + } + + private void getPending(Map<Identity,MemberView> views, BusinessGroup entry, SearchMembersParams params, + List<UserPropertyHandler> userPropertyHandlers, Locale locale) { + StringBuilder sb = new StringBuilder(); + sb.append("select ident from resourcereservation as reservation") + .append(" inner join reservation.identity as ident") + .append(" inner join fetch ident.user as identUser") + .append(" inner join businessgroup as grp on (reservation.resource.key = grp.resource.key)") + .append(" where grp.key=:groupKey"); + searchByIdentity(sb, params); + + TypedQuery<Identity> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Identity.class) + .setParameter("groupKey", entry.getKey()); + searchByIdentity(query, params); + + List<Identity> identities = query.getResultList(); + for(Identity identity:identities) { + views.computeIfAbsent(identity, id -> new MemberView(id, userPropertyHandlers, locale)).setPending(true); + } + } + + private void searchByIdentity(StringBuilder sb, SearchMembersParams params) { + if (params.getLogin() == null && (params.getUserPropertiesSearch() == null || params.getUserPropertiesSearch().isEmpty())) return; + + sb.append(" and ("); + + // append query for login + boolean appendOr = false; + + if (params.getLogin() != null) { + appendOr = true; + if (params.getLogin().contains("_") && dbInstance.isOracle()) { + //oracle needs special ESCAPE sequence to search for escaped strings + sb.append("lower(ident.name) like :login ESCAPE '\\'"); + } else if (dbInstance.isMySQL()) { + sb.append("ident.name like :login"); + } else { + sb.append("lower(ident.name) like :login"); + } + } + + // append queries for user fields + if (params.getUserPropertiesSearch() != null && !params.getUserPropertiesSearch().isEmpty()) { + // add other fields + for (String key : params.getUserPropertiesSearch().keySet()) { + if(appendOr) { + sb.append(" or "); + } else { + appendOr = true; + } + + if(dbInstance.isMySQL()) { + sb.append("identUser.").append(key).append(" like :").append(key).append("_value"); + } else { + sb.append("lower(identUser.").append(key).append(") like :").append(key).append("_value"); + } + if(dbInstance.isOracle()) { + sb.append(" escape '\\'"); + } + } + } + + sb.append(" )"); + } + + private void searchByIdentity(TypedQuery<?> query, SearchMembersParams params) { + if (params.getLogin() != null) { + String login = PersistenceHelper.makeFuzzyQueryString(params.getLogin()); + query.setParameter("login", login.toLowerCase()); + } + + // add user properties attributes + if (params.getUserPropertiesSearch() != null && !params.getUserPropertiesSearch().isEmpty()) { + for (Map.Entry<String, String> entry : params.getUserPropertiesSearch().entrySet()) { + String value = entry.getValue(); + value = PersistenceHelper.makeFuzzyQueryString(value); + query.setParameter(entry.getKey() + "_value", value.toLowerCase()); + } + } + } + + private void filterByOrigin(List<MemberView> memberList, SearchMembersParams params) { + if(params.getOrigin() == Origin.businessGroup) { + for(Iterator<MemberView> it=memberList.iterator(); it.hasNext(); ) { + MemberView m = it.next(); + if(m.getGroups() == null || m.getGroups().isEmpty()) { + it.remove(); + } + } + } else if(params.getOrigin() == Origin.curriculum) { + for(Iterator<MemberView> it=memberList.iterator(); it.hasNext(); ) { + MemberView m = it.next(); + if(m.getCurriculumElements() == null || m.getCurriculumElements().isEmpty()) { + it.remove(); + } + } + } else if(params.getOrigin() == Origin.repositoryEntry) { + for(Iterator<MemberView> it=memberList.iterator(); it.hasNext(); ) { + if(!StringHelper.containsNonWhitespace(it.next().getRepositoryEntryDisplayName())) { + it.remove(); + } + } + } + } + + /** + * This filter method preserve the multiple roles of a member. If we want only the waiting list but + * a member is in the waiting list and owner of the course, we want it to know. + * @param memberList + * @param params + * @return + */ + private void filterByRoles(Collection<MemberView> memberList, SearchMembersParams params) { + List<MemberView> members = new ArrayList<>(memberList); + + if(params.isRole(GroupRoles.owner)) { + for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { + if(it.next().getMemberShip().isOwner()) { + it.remove(); + } + } + } + + if(params.isRole(GroupRoles.participant)) { + for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { + if(it.next().getMemberShip().isParticipant()) { + it.remove(); + } + } + } + + if(params.isRole(GroupRoles.coach)) { + for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { + if(it.next().getMemberShip().isCoach()) { + it.remove(); + } + } + } + + if(params.isRole(GroupRoles.waiting)) { + for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { + if(it.next().getMemberShip().isBusinessGroupWaiting()) { + it.remove(); + } + } + } + + if(params.isPending()) { + for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { + if(it.next().isPending()) { + it.remove(); + } + } + } + + memberList.removeAll(members); + } +} diff --git a/src/main/java/org/olat/group/model/MemberView.java b/src/main/java/org/olat/group/model/MemberView.java new file mode 100644 index 0000000000000000000000000000000000000000..12fd89c36f4d564bf063d57c5f8f9c5f81c060d5 --- /dev/null +++ b/src/main/java/org/olat/group/model/MemberView.java @@ -0,0 +1,215 @@ +/** + * <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> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.group.model; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import org.olat.core.id.Identity; +import org.olat.group.BusinessGroupManagedFlag; +import org.olat.group.BusinessGroupShort; +import org.olat.group.ui.main.CourseMembership; +import org.olat.modules.curriculum.CurriculumElementManagedFlag; +import org.olat.modules.curriculum.CurriculumElementShort; +import org.olat.repository.RepositoryEntryManagedFlag; +import org.olat.user.UserPropertiesRow; +import org.olat.user.propertyhandlers.UserPropertyHandler; + +/** + * + * Initial date: 6 juin 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class MemberView extends UserPropertiesRow { + + private String repositoryEntryDisplayName; + private RepositoryEntryManagedFlag[] managedFlags; + + private List<BusinessGroupShort> groups; + private List<CurriculumElementShort> curriculumElements; + + private Date creationDate; + private Date lastModified; + + private boolean pending; + private boolean managedMembersRepo; + private final CourseMembership membership = new CourseMembership(); + + public MemberView(Identity identity, List<UserPropertyHandler> userPropertyHandlers, Locale locale) { + this(identity, userPropertyHandlers, locale, null, null); + } + + public MemberView(Identity identity, List<UserPropertyHandler> userPropertyHandlers, Locale locale, Date creationDate, Date lastModified) { + super(identity, userPropertyHandlers, locale); + this.creationDate = creationDate; + this.lastModified = lastModified; + } + + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + public Date getLastModified() { + return lastModified; + } + + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + public String getRepositoryEntryDisplayName() { + return repositoryEntryDisplayName; + } + + public void setRepositoryEntryDisplayName(String displayName) { + this.repositoryEntryDisplayName = displayName; + } + + public RepositoryEntryManagedFlag[] getManagedFlags() { + return managedFlags; + } + + public void setManagedFlags(RepositoryEntryManagedFlag[] managedFlags) { + this.managedFlags = managedFlags; + } + + public List<BusinessGroupShort> getGroups() { + return groups; + } + + public void setGroups(List<BusinessGroupShort> groups) { + this.groups = groups; + } + + public void addGroup(BusinessGroupShort group) { + if(groups == null) { + groups = new ArrayList<>(5); + } + groups.add(group); + } + + public List<CurriculumElementShort> getCurriculumElements() { + return curriculumElements; + } + + public void setCurriculumElements(List<CurriculumElementShort> curriculumElements) { + this.curriculumElements = curriculumElements; + } + + public void addCurriculumElement(CurriculumElementShort curriculumElement) { + if(curriculumElements == null) { + curriculumElements = new ArrayList<>(3); + } + curriculumElements.add(curriculumElement); + } + + public CourseMembership getMemberShip() { + return membership; + } + + public boolean isManagedMembersRepo() { + return managedMembersRepo; + } + + public void setManagedMembersRepo(boolean managedMembersRepo) { + this.managedMembersRepo = managedMembersRepo; + } + + public boolean isPending() { + return pending; + } + + public void setPending(boolean pending) { + this.pending = pending; + } + + public static class BusinessGroupShortImpl implements BusinessGroupShort { + + private final Long key; + private final String name; + private final BusinessGroupManagedFlag[] managedFlags; + + public BusinessGroupShortImpl(Long key, String name, String managedFlags) { + this.key = key; + this.name = name; + this.managedFlags = BusinessGroupManagedFlag.toEnum(managedFlags); + } + + @Override + public String getResourceableTypeName() { + return "BusinessGroup"; + } + + @Override + public Long getResourceableId() { + return key; + } + + @Override + public Long getKey() { + return key; + } + + @Override + public String getName() { + return name; + } + + @Override + public BusinessGroupManagedFlag[] getManagedFlags() { + return managedFlags; + } + } + + public static class CurriculumElementShortImpl implements CurriculumElementShort { + + private final Long key; + private final String displayName; + private final CurriculumElementManagedFlag[] managedFlags; + + public CurriculumElementShortImpl(Long key, String displayName, String managedFlags) { + this.key = key; + this.displayName = displayName; + this.managedFlags = CurriculumElementManagedFlag.toEnum(managedFlags); + } + + @Override + public Long getKey() { + return key; + } + + @Override + public String getDisplayName() { + return displayName; + } + + @Override + public CurriculumElementManagedFlag[] getManagedFlags() { + return managedFlags; + } + } +} diff --git a/src/main/java/org/olat/group/ui/edit/BusinessGroupMembersController.java b/src/main/java/org/olat/group/ui/edit/BusinessGroupMembersController.java index 1369f2bbd10855a3b76141d70ced179ac3d8160b..c9c7a91acad02095a51cba1bce79ac9d7879a30a 100644 --- a/src/main/java/org/olat/group/ui/edit/BusinessGroupMembersController.java +++ b/src/main/java/org/olat/group/ui/edit/BusinessGroupMembersController.java @@ -21,6 +21,7 @@ package org.olat.group.ui.edit; import java.util.List; +import org.olat.basesecurity.GroupRoles; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; @@ -97,7 +98,7 @@ public class BusinessGroupMembersController extends BasicController { configForm.setMembershipConfiguration(businessGroup); mainVC.put("configMembers", configForm.getInitialComponent()); - SearchMembersParams searchParams = new SearchMembersParams(false, false, false, true, true, true, true); + SearchMembersParams searchParams = new SearchMembersParams(true, GroupRoles.coach, GroupRoles.participant, GroupRoles.waiting); membersController = new MemberListController(ureq, getWindowControl(), toolbarPanel, businessGroup, searchParams); listenTo(membersController); diff --git a/src/main/java/org/olat/group/ui/edit/MemberListController.java b/src/main/java/org/olat/group/ui/edit/MemberListController.java index 59f82a63c9de7e43b47380b1c9a65bf1abf76e52..472a6ed9423f6df9ae0fbc81e6e071d03fbfaa9e 100644 --- a/src/main/java/org/olat/group/ui/edit/MemberListController.java +++ b/src/main/java/org/olat/group/ui/edit/MemberListController.java @@ -24,7 +24,7 @@ import org.olat.core.gui.components.stack.TooledStackedPanel; import org.olat.core.gui.control.WindowControl; import org.olat.group.BusinessGroup; import org.olat.group.ui.main.AbstractMemberListController; -import org.olat.group.ui.main.MemberView; +import org.olat.group.ui.main.MemberRow; import org.olat.group.ui.main.SearchMembersParams; /** @@ -42,7 +42,7 @@ public class MemberListController extends AbstractMemberListController { } @Override - protected void doOpenAssessmentTool(UserRequest ureq, MemberView member) { + protected void doOpenAssessmentTool(UserRequest ureq, MemberRow member) { // } diff --git a/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java b/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java index c8a0ced4a5404754cb79fec56ed955a17a7bc89a..f8ad7eb9281fbdf626e8747161750fffc586a094 100644 --- a/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java +++ b/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java @@ -20,14 +20,11 @@ package org.olat.group.ui.main; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; @@ -35,9 +32,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityModule; import org.olat.basesecurity.GroupRoles; -import org.olat.basesecurity.SearchIdentityParams; import org.olat.core.commons.persistence.DBFactory; -import org.olat.core.commons.persistence.PersistenceHelper; import org.olat.core.commons.persistence.SortKey; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; @@ -77,7 +72,6 @@ import org.olat.core.id.Roles; import org.olat.core.id.UserConstants; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; -import org.olat.core.util.StringHelper; import org.olat.core.util.Util; import org.olat.core.util.mail.ContactList; import org.olat.core.util.mail.ContactMessage; @@ -88,11 +82,12 @@ import org.olat.course.assessment.manager.UserCourseInformationsManager; import org.olat.course.member.MemberListController; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupManagedFlag; -import org.olat.group.BusinessGroupMembership; import org.olat.group.BusinessGroupModule; import org.olat.group.BusinessGroupService; import org.olat.group.BusinessGroupShort; +import org.olat.group.manager.MemberViewQueries; import org.olat.group.model.BusinessGroupMembershipChange; +import org.olat.group.model.MemberView; import org.olat.group.ui.main.MemberListTableModel.Cols; import org.olat.instantMessaging.InstantMessagingModule; import org.olat.instantMessaging.InstantMessagingService; @@ -104,11 +99,7 @@ import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryManagedFlag; import org.olat.repository.RepositoryManager; import org.olat.repository.RepositoryService; -import org.olat.repository.model.RepositoryEntryMembership; import org.olat.repository.model.RepositoryEntryPermissionChangeEvent; -import org.olat.resource.OLATResource; -import org.olat.resource.accesscontrol.ACService; -import org.olat.resource.accesscontrol.ResourceReservation; import org.olat.user.UserInfoMainController; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.UserPropertyHandler; @@ -160,6 +151,8 @@ public abstract class AbstractMemberListController extends FormBasicController i private boolean overrideManaged = false; private final boolean globallyManaged; + @Autowired + private MemberViewQueries memberQueries; @Autowired protected UserManager userManager; @Autowired @@ -177,8 +170,6 @@ public abstract class AbstractMemberListController extends FormBasicController i @Autowired private BusinessGroupModule groupModule; @Autowired - private ACService acService; - @Autowired private InstantMessagingModule imModule; @Autowired private InstantMessagingService imService; @@ -349,7 +340,7 @@ public abstract class AbstractMemberListController extends FormBasicController i if(event instanceof SelectionEvent) { SelectionEvent se = (SelectionEvent)event; String cmd = se.getCommand(); - MemberView row = memberListModel.getObject(se.getIndex()); + MemberRow row = memberListModel.getObject(se.getIndex()); if(TABLE_ACTION_IM.equals(cmd)) { doIm(ureq, row); } else if(TABLE_ACTION_EDIT.equals(cmd)) { @@ -370,38 +361,38 @@ public abstract class AbstractMemberListController extends FormBasicController i } } } else if(editButton == source) { - List<MemberView> selectedItems = getMultiSelectedRows(); + List<MemberRow> selectedItems = getMultiSelectedRows(); openEdit(ureq, selectedItems); } else if(mailButton == source) { - List<MemberView> selectedItems = getMultiSelectedRows(); + List<MemberRow> selectedItems = getMultiSelectedRows(); doSendMail(ureq, selectedItems); } else if(removeButton == source) { - List<MemberView> selectedItems = getMultiSelectedRows(); + List<MemberRow> selectedItems = getMultiSelectedRows(); confirmDelete(ureq, selectedItems); } else if(source instanceof FormLink) { FormLink link = (FormLink)source; String cmd = link.getCmd(); if("tools".equals(cmd)) { - MemberView row = (MemberView)link.getUserObject(); + MemberRow row = (MemberRow)link.getUserObject(); doOpenTools(ureq, row, link); } else if("im".equals(cmd)) { - MemberView row = (MemberView)link.getUserObject(); + MemberRow row = (MemberRow)link.getUserObject(); doIm(ureq, row); } } super.formInnerEvent(ureq, source, event); } - private List<MemberView> getMultiSelectedRows() { + private List<MemberRow> getMultiSelectedRows() { Set<Integer> selections = membersTable.getMultiSelectedIndex(); - List<MemberView> rows = new ArrayList<>(selections.size()); + List<MemberRow> rows = new ArrayList<>(selections.size()); if(selections.isEmpty()) { //do nothing } else { for(Integer i:selections) { int index = i.intValue(); if(index >= 0 && index < memberListModel.getRowCount()) { - MemberView row = memberListModel.getObject(index); + MemberRow row = memberListModel.getObject(index); if(row != null) { rows.add(row); } @@ -476,7 +467,7 @@ public abstract class AbstractMemberListController extends FormBasicController i editSingleMemberCtrl = null; } - protected void confirmDelete(UserRequest ureq, List<MemberView> members) { + protected void confirmDelete(UserRequest ureq, List<MemberRow> members) { if(members.isEmpty()) { showWarning("error.select.one.user"); } else { @@ -485,8 +476,8 @@ public abstract class AbstractMemberListController extends FormBasicController i : repositoryService.countMembers(repoEntry, GroupRoles.owner.name()); int numOfRemovedOwner = 0; - List<Long> identityKeys = new ArrayList<Long>(); - for(MemberView member:members) { + List<Long> identityKeys = new ArrayList<>(); + for(MemberRow member:members) { identityKeys.add(member.getIdentityKey()); if(member.getMembership().isOwner()) { numOfRemovedOwner++; @@ -507,7 +498,7 @@ public abstract class AbstractMemberListController extends FormBasicController i } } - protected void openEdit(UserRequest ureq, MemberView member) { + protected void openEdit(UserRequest ureq, MemberRow member) { if(editSingleMemberCtrl != null) return; Identity identity = securityManager.loadIdentityByKey(member.getIdentityKey()); @@ -519,7 +510,7 @@ public abstract class AbstractMemberListController extends FormBasicController i listenTo(cmc); } - protected void openEdit(UserRequest ureq, List<MemberView> members) { + protected void openEdit(UserRequest ureq, List<MemberRow> members) { if(members.isEmpty()) { showWarning("error.select.one.user"); } else { @@ -542,16 +533,22 @@ public abstract class AbstractMemberListController extends FormBasicController i } protected void doSearch(String search) { - getSearchParams().setSearchString(search); + Map<String,String> propertiesSearch = new HashMap<>(); + for(UserPropertyHandler handler:userPropertyHandlers) { + propertiesSearch.put(handler.getName(), search); + } + getSearchParams().setUserPropertiesSearch(propertiesSearch); + getSearchParams().setLogin(search); reloadModel(); } protected void doResetSearch() { - getSearchParams().setSearchString(null); + getSearchParams().setLogin(null); + getSearchParams().setUserPropertiesSearch(null); reloadModel(); } - private void doOpenTools(UserRequest ureq, MemberView row, FormLink link) { + private void doOpenTools(UserRequest ureq, MemberRow row, FormLink link) { removeAsListenerAndDispose(toolsCtrl); removeAsListenerAndDispose(toolsCalloutCtrl); @@ -569,7 +566,7 @@ public abstract class AbstractMemberListController extends FormBasicController i * @param ureq * @param member */ - protected void doIm(UserRequest ureq, MemberView member) { + protected void doIm(UserRequest ureq, MemberRow member) { Buddy buddy = imService.getBuddyById(member.getIdentityKey()); OpenInstantMessageEvent e = new OpenInstantMessageEvent(ureq, buddy); ureq.getUserSession().getSingleUserEventCenter().fireEventToListenersOf(e, InstantMessagingService.TOWER_EVENT_ORES); @@ -634,7 +631,7 @@ public abstract class AbstractMemberListController extends FormBasicController i reloadModel(); } - protected void doSendMail(UserRequest ureq, List<MemberView> members) { + protected void doSendMail(UserRequest ureq, List<MemberRow> members) { List<Long> identityKeys = getMemberKeys(members); List<Identity> identities = securityManager.loadIdentityByKeys(identityKeys); if(identities.isEmpty()) { @@ -657,7 +654,7 @@ public abstract class AbstractMemberListController extends FormBasicController i listenTo(cmc); } - protected void doGraduate(List<MemberView> members) { + protected void doGraduate(List<MemberRow> members) { if(businessGroup != null) { List<Long> identityKeys = getMemberKeys(members); List<Identity> identitiesToGraduate = securityManager.loadIdentityByKeys(identityKeys); @@ -666,7 +663,7 @@ public abstract class AbstractMemberListController extends FormBasicController i } else { Map<Long, BusinessGroup> groupsMap = new HashMap<>(); Map<BusinessGroup, List<Identity>> graduatesMap = new HashMap<>(); - for(MemberView member:members) { + for(MemberRow member:members) { List<BusinessGroupShort> groups = member.getGroups(); if(groups != null && groups.size() > 0) { Identity memberIdentity = securityManager.loadIdentityByKey(member.getIdentityKey()); @@ -699,7 +696,7 @@ public abstract class AbstractMemberListController extends FormBasicController i reloadModel(); } - protected void doOpenVisitingCard(UserRequest ureq, MemberView member) { + protected void doOpenVisitingCard(UserRequest ureq, MemberRow member) { removeAsListenerAndDispose(visitingCardCtrl); Identity choosenIdentity = securityManager.loadIdentityByKey(member.getIdentityKey()); visitingCardCtrl = new UserInfoMainController(ureq, getWindowControl(), choosenIdentity, false, false); @@ -709,7 +706,7 @@ public abstract class AbstractMemberListController extends FormBasicController i toolbarPanel.pushController(fullname, visitingCardCtrl); } - protected void doOpenContact(UserRequest ureq, MemberView member) { + protected void doOpenContact(UserRequest ureq, MemberRow member) { removeAsListenerAndDispose(contactCtrl); Identity choosenIdentity = securityManager.loadIdentityByKey(member.getIdentityKey()); @@ -728,12 +725,12 @@ public abstract class AbstractMemberListController extends FormBasicController i toolbarPanel.pushController(fullname, contactCtrl); } - protected abstract void doOpenAssessmentTool(UserRequest ureq, MemberView member); + protected abstract void doOpenAssessmentTool(UserRequest ureq, MemberRow member); - protected List<Long> getMemberKeys(List<MemberView> members) { + protected List<Long> getMemberKeys(List<MemberRow> members) { List<Long> keys = new ArrayList<Long>(members.size()); if(members != null && !members.isEmpty()) { - for(MemberView member:members) { + for(MemberRow member:members) { keys.add(member.getIdentityKey()); } } @@ -746,101 +743,36 @@ public abstract class AbstractMemberListController extends FormBasicController i updateTableModel(getSearchParams()); } - protected List<MemberView> updateTableModel(SearchMembersParams params) { - //course membership - boolean managedMembersRepo = - RepositoryEntryManagedFlag.isManaged(repoEntry, RepositoryEntryManagedFlag.membersmanagement); - - List<RepositoryEntryMembership> repoMemberships = - repoEntry == null ? Collections.<RepositoryEntryMembership>emptyList() - : repositoryManager.getRepositoryEntryMembership(repoEntry); - - //groups membership - List<BusinessGroup> groups = - repoEntry == null ? Collections.singletonList(businessGroup) - : businessGroupService.findBusinessGroups(null, repoEntry, 0, -1); - - List<Long> groupKeys = new ArrayList<Long>(); - Map<Long,BusinessGroupShort> keyToGroupMap = new HashMap<>(); - for(BusinessGroup group:groups) { - groupKeys.add(group.getKey()); - keyToGroupMap.put(group.getKey(), group); - } - - List<BusinessGroupMembership> memberships = groups.isEmpty() ? Collections.<BusinessGroupMembership>emptyList() : - businessGroupService.getBusinessGroupsMembership(groups); - - //get identities - Set<Long> identityKeys = new HashSet<>(); - for(RepositoryEntryMembership membership: repoMemberships) { - identityKeys.add(membership.getIdentityKey()); - } - for(BusinessGroupMembership membership:memberships) { - identityKeys.add(membership.getIdentityKey()); - } - - List<Identity> identities; - if(identityKeys.isEmpty()) { - identities = new ArrayList<>(0); - } else { - identities = filterIdentities(params, identityKeys); + protected List<MemberRow> updateTableModel(SearchMembersParams params) { + List<MemberView> memberViews; + if(repoEntry != null) { + memberViews = memberQueries.getRepositoryEntryMembers(repoEntry, params, userPropertyHandlers, getLocale()); + } else if(businessGroup != null) { + memberViews = memberQueries.getBusinessGroupMembers(businessGroup, params, userPropertyHandlers, getLocale()); + } else { + memberViews = Collections.emptyList(); } - Map<Long,MemberView> keyToMemberMap = new HashMap<>(); - List<MemberView> memberList = new ArrayList<>(); - Locale locale = getLocale(); - - //reservations - if(params.isPending()) { - List<OLATResource> resourcesForReservations = new ArrayList<>(); - if(repoEntry != null) { - resourcesForReservations.add(repoEntry.getOlatResource()); - } - for(BusinessGroup group:groups) { - resourcesForReservations.add(group.getResource()); - } - List<ResourceReservation> reservations = acService.getReservations(resourcesForReservations); - List<Long> pendingIdentityKeys = new ArrayList<>(reservations.size()); - for(ResourceReservation reservation:reservations) { - pendingIdentityKeys.add(reservation.getIdentity().getKey()); - } - - if(StringHelper.containsNonWhitespace(params.getSearchString()) - || StringHelper.containsNonWhitespace(params.getLogin()) - || (params.getUserPropertiesSearch() != null && !params.getUserPropertiesSearch().isEmpty())) { - - List<Identity> pendingIdentities = filterIdentities(params, pendingIdentityKeys); - pendingIdentityKeys.retainAll(PersistenceHelper.toKeys(pendingIdentities)); - } - - for(ResourceReservation reservation:reservations) { - Identity identity = reservation.getIdentity(); - if(pendingIdentityKeys.contains(identity.getKey())) { - MemberView member = new MemberView(identity, userPropertyHandlers, locale); - member.getMembership().setPending(true); - memberList.add(member); - forgeLinks(member); - keyToMemberMap.put(identity.getKey(), member); - } - } - } + Map<Long,MemberRow> keyToMemberMap = new HashMap<>(); + List<MemberRow> memberList = new ArrayList<>(); Long me = getIdentity().getKey(); Set<Long> loadStatus = new HashSet<>(); - for(Identity identity:identities) { - MemberView member = new MemberView(identity, userPropertyHandlers, locale); + for(MemberView memberView:memberViews) { + Long identityKey = memberView.getIdentityKey(); + MemberRow member = new MemberRow(memberView); if(chatEnabled) { - if(identity.getKey().equals(me)) { + if(identityKey.equals(me)) { member.setOnlineStatus("me"); - } else if(sessionManager.isOnline(identity.getKey())) { - loadStatus.add(identity.getKey()); + } else if(sessionManager.isOnline(identityKey)) { + loadStatus.add(identityKey); } else { member.setOnlineStatus(Presence.unavailable.name()); } } memberList.add(member); forgeLinks(member); - keyToMemberMap.put(identity.getKey(), member); + keyToMemberMap.put(identityKey, member); } if(loadStatus.size() > 0) { @@ -848,7 +780,7 @@ public abstract class AbstractMemberListController extends FormBasicController i Map<Long,String> statusMap = imService.getBuddyStatus(statusToLoadList); for(Long toLoad:statusToLoadList) { String status = statusMap.get(toLoad); - MemberView member = keyToMemberMap.get(toLoad); + MemberRow member = keyToMemberMap.get(toLoad); if(status == null) { member.setOnlineStatus(Presence.available.name()); } else { @@ -856,105 +788,26 @@ public abstract class AbstractMemberListController extends FormBasicController i } } } - - for(BusinessGroupMembership membership:memberships) { - Long identityKey = membership.getIdentityKey(); - MemberView memberView = keyToMemberMap.get(identityKey); - if(memberView != null) { - memberView.setFirstTime(membership.getCreationDate()); - memberView.setLastTime(membership.getLastModified()); - if(membership.isOwner()) { - memberView.getMembership().setGroupTutor(true); - } - if(membership.isParticipant()) { - memberView.getMembership().setGroupParticipant(true); - } - if(membership.isWaiting()) { - memberView.getMembership().setGroupWaiting(true); - } - - Long groupKey = membership.getGroupKey(); - BusinessGroupShort group = keyToGroupMap.get(groupKey); - memberView.addGroup(group); - } - } - for(RepositoryEntryMembership membership:repoMemberships) { - Long identityKey = membership.getIdentityKey(); - MemberView memberView = keyToMemberMap.get(identityKey); - if(memberView != null) { - memberView.setFirstTime(membership.getCreationDate()); - memberView.setLastTime(membership.getLastModified()); - memberView.getMembership().setManagedMembersRepo(managedMembersRepo); - if(membership.isOwner()) { - memberView.getMembership().setRepoOwner(true); - } - if(membership.isCoach()) { - memberView.getMembership().setRepoTutor(true); - } - if(membership.isParticipant()) { - memberView.getMembership().setRepoParticipant(true); - } - } - } - - if(repoEntry != null) { + if(repoEntry != null && isLastVisitVisible) { Map<Long,Date> lastLaunchDates = userInfosMgr.getRecentLaunchDates(repoEntry.getOlatResource()); - for(MemberView memberView:keyToMemberMap.values()) { - Long identityKey = memberView.getIdentityKey(); + for(MemberRow memberView:keyToMemberMap.values()) { + Long identityKey = memberView.getView().getIdentityKey(); Date date = lastLaunchDates.get(identityKey); memberView.setLastTime(date); } } //the order of the filter is important - filterByRoles(memberList, params); - filterByOrigin(memberList, params); + //filterByRoles(memberList, params); + //filterByOrigin(memberList, params); memberListModel.setObjects(memberList); membersTable.reset(true, true, true); return memberList; } - private List<Identity> filterIdentities(SearchMembersParams params, Collection<Long> identityKeys) { - SearchIdentityParams idParams = new SearchIdentityParams(); - if(StringHelper.containsNonWhitespace(params.getSearchString())) { - String searchString = params.getSearchString(); - - Map<String,String> propertiesSearch = new HashMap<>(); - for(UserPropertyHandler handler:userPropertyHandlers) { - propertiesSearch.put(handler.getName(), searchString); - } - idParams.setLogin(searchString); - idParams.setUserProperties(propertiesSearch); - } else { - if(params.getUserPropertiesSearch() != null && !params.getUserPropertiesSearch().isEmpty()) { - idParams.setUserProperties(params.getUserPropertiesSearch()); - } - if(StringHelper.containsNonWhitespace(params.getLogin())) { - idParams.setLogin(params.getLogin()); - } - } - - List<Long> identityKeyList = new ArrayList<>(identityKeys); - List<Identity> identities = new ArrayList<>(identityKeyList.size()); - - int count = 0; - int batch = 500; - do { - int toIndex = Math.min(count + batch, identityKeyList.size()); - List<Long> toLoad = identityKeyList.subList(count, toIndex); - idParams.setIdentityKeys(toLoad); - - List<Identity> batchOfIdentities = securityManager.getIdentitiesByPowerSearch(idParams, 0, -1); - identities.addAll(batchOfIdentities); - count += batch; - } while(count < identityKeyList.size()); - - return identities; - } - - protected void forgeLinks(MemberView row) { + protected void forgeLinks(MemberRow row) { FormLink toolsLink = uifactory.addFormLink("tools_" + counter.incrementAndGet(), "tools", "", null, null, Link.NONTRANSLATED); toolsLink.setIconLeftCSS("o_icon o_icon_actions o_icon-lg"); toolsLink.setUserObject(row); @@ -966,95 +819,6 @@ public abstract class AbstractMemberListController extends FormBasicController i row.setChatLink(chatLink); } - private void filterByOrigin(List<MemberView> memberList, SearchMembersParams params) { - if(params.isGroupOrigin() && params.isRepoOrigin()) { - //do nothing not very useful :-) - } else if(params.isGroupOrigin()) { - for(Iterator<MemberView> it=memberList.iterator(); it.hasNext(); ) { - CourseMembership m = it.next().getMembership(); - if(!m.isGroupTutor() && !m.isGroupParticipant() && !m.isGroupWaiting()) { - it.remove(); - } - } - } else if(params.isRepoOrigin()) { - for(Iterator<MemberView> it=memberList.iterator(); it.hasNext(); ) { - CourseMembership m = it.next().getMembership(); - if(!m.isRepoOwner() && !m.isRepoTutor() && !m.isRepoParticipant()) { - it.remove(); - } - } - } - } - - /** - * This filter method preserve the multiple roles of a member. If we want only the waiting list but - * a member is in the waiting list and owner of the course, we want it to know. - * @param memberList - * @param params - * @return - */ - private void filterByRoles(List<MemberView> memberList, SearchMembersParams params) { - List<MemberView> members = new ArrayList<MemberView>(memberList); - - if(params.isRepoOwners()) { - for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { - if(it.next().getMembership().isRepoOwner()) { - it.remove(); - } - } - } - - if(params.isRepoTutors()) { - for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { - if(it.next().getMembership().isRepoTutor()) { - it.remove(); - } - } - } - - if(params.isRepoParticipants()) { - for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { - if(it.next().getMembership().isRepoParticipant()) { - it.remove(); - } - } - } - - if(params.isGroupTutors()) { - for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { - if(it.next().getMembership().isGroupTutor()) { - it.remove(); - } - } - } - - if(params.isGroupParticipants()) { - for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { - if(it.next().getMembership().isGroupParticipant()) { - it.remove(); - } - } - } - - if(params.isGroupWaitingList()) { - for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { - if(it.next().getMembership().isGroupWaiting()) { - it.remove(); - } - } - } - - if(params.isPending()) { - for(Iterator<MemberView> it=members.iterator(); it.hasNext(); ) { - if(it.next().getMembership().isPending()) { - it.remove(); - } - } - } - - memberList.removeAll(members); - } - private class MailConfirmation { private final List<Identity> members; private final MemberPermissionChangeEvent e; @@ -1075,11 +839,11 @@ public abstract class AbstractMemberListController extends FormBasicController i private class ToolsController extends BasicController { - private final MemberView row; + private final MemberRow row; private final VelocityContainer mainVC; - public ToolsController(UserRequest ureq, WindowControl wControl, MemberView row) { + public ToolsController(UserRequest ureq, WindowControl wControl, MemberRow row) { super(ureq, wControl); this.row = row; @@ -1095,15 +859,16 @@ public abstract class AbstractMemberListController extends FormBasicController i links.add("-"); - if(row.getMembership().isGroupWaiting() && !readOnly) { + if(row.getMembership().isBusinessGroupWaiting() && !readOnly) { addLink("table.header.graduate", TABLE_ACTION_GRADUATE, "o_icon o_icon_graduate", links); } - if(!readOnly) { + if(!readOnly && (row.getMembership().isRepositoryEntryMember() || row.getMembership().isBusinessGroupMember())) { addLink("edit.member", TABLE_ACTION_EDIT, "o_icon o_icon_edit", links); } - if(!globallyManaged || overrideManaged) { + if((!globallyManaged || overrideManaged) + && (row.getMembership().isRepositoryEntryMember() || row.getMembership().isBusinessGroupMember())) { addLink("table.header.remove", TABLE_ACTION_REMOVE, "o_icon o_icon_remove", links); } diff --git a/src/main/java/org/olat/group/ui/main/CourseMembership.java b/src/main/java/org/olat/group/ui/main/CourseMembership.java index 926e0ed192e84b102f63709a574ed65b9d65d79f..3ea445b99fec02e4ab9b44a0dd33e9cfd18ce976 100644 --- a/src/main/java/org/olat/group/ui/main/CourseMembership.java +++ b/src/main/java/org/olat/group/ui/main/CourseMembership.java @@ -19,18 +19,26 @@ */ package org.olat.group.ui.main; +import org.olat.basesecurity.GroupRoles; + /** * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ public class CourseMembership { - private boolean repoOwner; - private boolean repoTutor; - private boolean repoParticipant; - private boolean groupTutor; - private boolean groupParticipant; - private boolean groupWaiting; + private boolean repositoryEntryOwner; + private boolean repositoryEntryCoach; + private boolean repositoryEntryParticipant; + + private boolean businessGroupCoach; + private boolean businessGroupParticipant; + private boolean businessGroupWaiting; + + private boolean curriculumElementCoach; + private boolean curriculumElementParticipant; + private boolean curriculumElementOwner; + private boolean pending; private boolean managedMembersRepo; @@ -39,19 +47,27 @@ public class CourseMembership { } public boolean isOwner() { - return repoOwner; + return repositoryEntryOwner || curriculumElementOwner; } - public boolean isTutor() { - return repoTutor || groupTutor; + public boolean isCoach() { + return repositoryEntryCoach || businessGroupCoach || curriculumElementCoach; } public boolean isParticipant() { - return repoParticipant || groupParticipant; + return repositoryEntryParticipant || businessGroupParticipant || curriculumElementParticipant; + } + + public boolean isRepositoryEntryMember() { + return repositoryEntryOwner || repositoryEntryCoach || repositoryEntryParticipant; + } + + public boolean isBusinessGroupMember() { + return businessGroupCoach || businessGroupParticipant || businessGroupWaiting; } public boolean isWaiting() { - return groupWaiting; + return businessGroupWaiting; } public boolean isPending() { @@ -70,51 +86,106 @@ public class CourseMembership { this.managedMembersRepo = managedMembersRepo; } - public boolean isRepoOwner() { - return repoOwner; + public boolean isRepositoryEntryOwner() { + return repositoryEntryOwner; + } + + public void setRepositoryEntryOwner(boolean repositoryEntryOwner) { + this.repositoryEntryOwner = repositoryEntryOwner; + } + + public boolean isRepositoryEntryCoach() { + return repositoryEntryCoach; + } + + public void setRepositoryEntryCoach(boolean repositoryEntryCoach) { + this.repositoryEntryCoach = repositoryEntryCoach; + } + + public boolean isRepositoryEntryParticipant() { + return repositoryEntryParticipant; + } + + public void setRepositoryEntryParticipant(boolean repositoryEntryParticipant) { + this.repositoryEntryParticipant = repositoryEntryParticipant; } - public void setRepoOwner(boolean repoOwner) { - this.repoOwner = repoOwner; + public void setRepositoryEntryRole(String role) { + if(GroupRoles.participant.name().equals(role)) { + setRepositoryEntryParticipant(true); + } else if(GroupRoles.coach.name().equals(role)) { + setRepositoryEntryCoach(true); + } else if(GroupRoles.owner.name().equals(role)) { + setRepositoryEntryOwner(true); + } } - public boolean isRepoTutor() { - return repoTutor; + public boolean isBusinessGroupCoach() { + return businessGroupCoach; } - public void setRepoTutor(boolean repoTutor) { - this.repoTutor = repoTutor; + public void setBusinessGroupCoach(boolean businessGroupCoach) { + this.businessGroupCoach = businessGroupCoach; } - public boolean isRepoParticipant() { - return repoParticipant; + public boolean isBusinessGroupParticipant() { + return businessGroupParticipant; } - public void setRepoParticipant(boolean repoParticipant) { - this.repoParticipant = repoParticipant; + public void setBusinessGroupParticipant(boolean businessGroupParticipant) { + this.businessGroupParticipant = businessGroupParticipant; } - public boolean isGroupTutor() { - return groupTutor; + public boolean isBusinessGroupWaiting() { + return businessGroupWaiting; } - public void setGroupTutor(boolean groupTutor) { - this.groupTutor = groupTutor; + public void setBusinessGroupWaiting(boolean businessGroupWaiting) { + this.businessGroupWaiting = businessGroupWaiting; + } + + public void setBusinessGroupRole(String role) { + if(GroupRoles.participant.name().equals(role)) { + setBusinessGroupParticipant(true); + } else if(GroupRoles.coach.name().equals(role)) { + setBusinessGroupCoach(true); + } else if(GroupRoles.waiting.name().equals(role)) { + setBusinessGroupWaiting(true); + } } - public boolean isGroupParticipant() { - return groupParticipant; + public boolean isCurriculumElementOwner() { + return curriculumElementOwner; } - public void setGroupParticipant(boolean groupParticipant) { - this.groupParticipant = groupParticipant; + public void setCurriculumElementOwner(boolean curriculumElementOwner) { + this.curriculumElementOwner = curriculumElementOwner; } - public boolean isGroupWaiting() { - return groupWaiting; + public boolean isCurriculumElementCoach() { + return curriculumElementCoach; } - public void setGroupWaiting(boolean groupWaiting) { - this.groupWaiting = groupWaiting; + public void setCurriculumElementCoach(boolean curriculumElementCoach) { + this.curriculumElementCoach = curriculumElementCoach; } + + public boolean isCurriculumElementParticipant() { + return curriculumElementParticipant; + } + + public void setCurriculumElementParticipant(boolean curriculumElementParticipant) { + this.curriculumElementParticipant = curriculumElementParticipant; + } + + public void setCurriculumElementRole(String role) { + if(GroupRoles.participant.name().equals(role)) { + setCurriculumElementParticipant(true); + } else if(GroupRoles.coach.name().equals(role)) { + setCurriculumElementCoach(true); + } else if(GroupRoles.owner.name().equals(role)) { + setCurriculumElementOwner(true); + } + } + } \ No newline at end of file diff --git a/src/main/java/org/olat/group/ui/main/CourseMembershipComparator.java b/src/main/java/org/olat/group/ui/main/CourseMembershipComparator.java index 24023401057cd08f24c5c1fef005ebd26e7b7f06..514c5e2d9bcefba76a690f58202cf18cef2fe323 100644 --- a/src/main/java/org/olat/group/ui/main/CourseMembershipComparator.java +++ b/src/main/java/org/olat/group/ui/main/CourseMembershipComparator.java @@ -32,57 +32,66 @@ public class CourseMembershipComparator implements Comparator<CourseMembership> @Override public int compare(CourseMembership m1, CourseMembership m2) { - if(m1.isRepoOwner()) { - if(m2.isRepoOwner()) { + if(m1.isRepositoryEntryOwner()) { + if(m2.isRepositoryEntryOwner()) { return 0; } return 1; - } else if(m2.isRepoOwner()) { + } else if(m2.isRepositoryEntryOwner()) { return -1; } - if(m1.isGroupTutor()) { - if(m2.isGroupTutor()) { + if(m1.isCurriculumElementOwner()) { + if(m2.isCurriculumElementOwner()) { return 0; } return 1; - } else if(m2.isGroupTutor()) { + } else if(m2.isCurriculumElementOwner()) { return -1; } - if(m1.isRepoTutor()) { - if(m2.isRepoTutor()) { + if(m1.isBusinessGroupCoach()) { + if(m2.isBusinessGroupCoach()) { return 0; } return 1; - } else if(m2.isRepoTutor()) { + } else if(m2.isBusinessGroupCoach()) { return -1; } - if(m1.isGroupWaiting()) { - if(m2.isGroupWaiting()) { + if(m1.isRepositoryEntryCoach()) { + if(m2.isRepositoryEntryCoach()) { return 0; } return 1; - } else if(m2.isGroupWaiting()) { + } else if(m2.isRepositoryEntryCoach()) { return -1; } - if(m1.isGroupParticipant()) { - if(m2.isGroupParticipant()) { + if(m1.isBusinessGroupWaiting()) { + if(m2.isBusinessGroupWaiting()) { return 0; } return 1; - } else if(m2.isGroupParticipant()) { + } else if(m2.isBusinessGroupWaiting()) { return -1; } - if(m1.isRepoParticipant()) { - if(m2.isRepoParticipant()) { + if(m1.isBusinessGroupParticipant()) { + if(m2.isBusinessGroupParticipant()) { return 0; } return 1; - } else if(m2.isRepoParticipant()) { + } else if(m2.isBusinessGroupParticipant()) { + return -1; + } + + if(m1.isRepositoryEntryParticipant()) { + if(m2.isRepositoryEntryParticipant()) { + return 0; + } + return 1; + } else if(m2.isRepositoryEntryParticipant()) { return -1; } return 0; diff --git a/src/main/java/org/olat/group/ui/main/CourseRoleCellRenderer.java b/src/main/java/org/olat/group/ui/main/CourseRoleCellRenderer.java index b5ac5f0b0a756c9470c2badf941f413c04337b3f..75a828cbb6f59adba55a797268228db774a0e55a 100644 --- a/src/main/java/org/olat/group/ui/main/CourseRoleCellRenderer.java +++ b/src/main/java/org/olat/group/ui/main/CourseRoleCellRenderer.java @@ -23,7 +23,6 @@ import java.util.Locale; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent; -import org.olat.core.gui.components.table.CustomCellRenderer; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; import org.olat.core.gui.render.URLBuilder; @@ -34,7 +33,7 @@ import org.olat.core.util.Util; * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class CourseRoleCellRenderer implements CustomCellRenderer, FlexiCellRenderer { +public class CourseRoleCellRenderer implements FlexiCellRenderer { private final Translator translator; @@ -49,13 +48,6 @@ public class CourseRoleCellRenderer implements CustomCellRenderer, FlexiCellRend render(target, (CourseMembership) cellValue); } } - - @Override - public void render(StringOutput sb, Renderer renderer, Object val, Locale locale, int alignment, String action) { - if (val instanceof CourseMembership) { - render(sb, (CourseMembership) val); - } - } private void render(StringOutput sb, CourseMembership membership) { boolean and = false; @@ -63,22 +55,35 @@ public class CourseRoleCellRenderer implements CustomCellRenderer, FlexiCellRend and = and(sb, and); sb.append(translator.translate("role.repo.owner")); } - if(membership.isRepoTutor()) { + if(membership.isRepositoryEntryCoach()) { and = and(sb, and); sb.append(translator.translate("role.repo.tutor")); } - if(membership.isGroupTutor()) { + if(membership.isBusinessGroupCoach()) { and = and(sb, and); sb.append(translator.translate("role.group.tutor")); } - if(membership.isRepoParticipant()) { + if(membership.isRepositoryEntryParticipant()) { and = and(sb, and); sb.append(translator.translate("role.repo.participant")); } - if(membership.isGroupParticipant()) { + if(membership.isBusinessGroupParticipant()) { and = and(sb, and); sb.append(translator.translate("role.group.participant")); } + if(membership.isCurriculumElementParticipant()) { + and = and(sb, and); + sb.append(translator.translate("role.curriculum.participant")); + } + if(membership.isCurriculumElementCoach()) { + and = and(sb, and); + sb.append(translator.translate("role.curriculum.coach")); + } + if(membership.isCurriculumElementOwner()) { + and = and(sb, and); + sb.append(translator.translate("role.curriculum.owner")); + } + if(membership.isWaiting()) { and = and(sb, and); sb.append(translator.translate("role.group.waiting")); diff --git a/src/main/java/org/olat/group/ui/main/GraduateColumnDescriptor.java b/src/main/java/org/olat/group/ui/main/GraduateColumnDescriptor.java index a920940af4e03700e286611e997f260618b055a9..e45ea0c3a3ce61a89d28e456f1389bbf83ebbab8 100644 --- a/src/main/java/org/olat/group/ui/main/GraduateColumnDescriptor.java +++ b/src/main/java/org/olat/group/ui/main/GraduateColumnDescriptor.java @@ -43,7 +43,7 @@ public class GraduateColumnDescriptor extends DefaultColumnDescriptor { CourseMembership membership = (CourseMembership)table.getTableDataModel() .getValueAt(sortedRow, MemberListTableModel.Cols.role.ordinal()); - if(membership.isGroupWaiting()) { + if(membership.isBusinessGroupWaiting()) { return super.getAction(row); } return null; @@ -56,7 +56,7 @@ public class GraduateColumnDescriptor extends DefaultColumnDescriptor { CourseMembership membership = (CourseMembership)table.getTableDataModel() .getValueAt(sortedRow, MemberListTableModel.Cols.role.ordinal()); - if(membership.isGroupWaiting()) { + if(membership.isBusinessGroupWaiting()) { sb.append(translator.translate(getHeaderKey())); } } diff --git a/src/main/java/org/olat/group/ui/main/GroupCellRenderer.java b/src/main/java/org/olat/group/ui/main/GroupCellRenderer.java index ff004d30fd7385dc12d62be150b2a7b6606ff755..5088ea1ffb74c762dc4a5974bc9b7954d0b27c70 100644 --- a/src/main/java/org/olat/group/ui/main/GroupCellRenderer.java +++ b/src/main/java/org/olat/group/ui/main/GroupCellRenderer.java @@ -20,52 +20,56 @@ package org.olat.group.ui.main; import java.util.List; -import java.util.Locale; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent; -import org.olat.core.gui.components.table.CustomCellRenderer; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; import org.olat.core.gui.render.URLBuilder; import org.olat.core.gui.translator.Translator; import org.olat.core.util.StringHelper; import org.olat.group.BusinessGroupShort; +import org.olat.modules.curriculum.CurriculumElementShort; /** * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class GroupCellRenderer implements CustomCellRenderer, FlexiCellRenderer { +public class GroupCellRenderer implements FlexiCellRenderer { @Override public void render(Renderer renderer, StringOutput target, Object cellValue, int row, FlexiTableComponent source, URLBuilder ubu, Translator translator) { - if (cellValue instanceof MemberView) { - render(target, (MemberView) cellValue); - } - } - - @Override - public void render(StringOutput sb, Renderer renderer, Object val, Locale locale, int alignment, String action) { - if (val instanceof MemberView) { - render(sb, (MemberView) val); + if (cellValue instanceof MemberRow) { + render(target, (MemberRow) cellValue); } } - private void render(StringOutput sb, MemberView member) { + private void render(StringOutput sb, MemberRow member) { + boolean and = false; List<BusinessGroupShort> groups = member.getGroups(); if(groups != null && !groups.isEmpty()) { - boolean and = false; for(BusinessGroupShort group:groups) { and = and(sb, and); - if(group.getName() == null) { + if(group.getName() == null && group.getKey() != null) { sb.append(group.getKey()); } else { sb.append(StringHelper.escapeHtml(group.getName())); } } } + + List<CurriculumElementShort> curriculumElements = member.getCurriculumElements(); + if(curriculumElements != null && !curriculumElements.isEmpty()) { + for(CurriculumElementShort curriculumElement:curriculumElements) { + and = and(sb, and); + if(curriculumElement.getDisplayName() == null && curriculumElement.getKey() != null) { + sb.append(curriculumElement.getKey()); + } else { + sb.append(StringHelper.escapeHtml(curriculumElement.getDisplayName())); + } + } + } } private final boolean and(StringOutput sb, boolean and) { diff --git a/src/main/java/org/olat/group/ui/main/GroupMemberViewComparator.java b/src/main/java/org/olat/group/ui/main/GroupMemberViewComparator.java index c81cdbbe0d409e63a4d37587ab9745b42c5e50fd..08e11ed8a5d57d2ca32863aa4b5002063bf6d7b0 100644 --- a/src/main/java/org/olat/group/ui/main/GroupMemberViewComparator.java +++ b/src/main/java/org/olat/group/ui/main/GroupMemberViewComparator.java @@ -32,7 +32,7 @@ import org.olat.group.BusinessGroupShort; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class GroupMemberViewComparator implements Comparator<MemberView> { +public class GroupMemberViewComparator implements Comparator<MemberRow> { private Collator collator; @@ -41,7 +41,7 @@ public class GroupMemberViewComparator implements Comparator<MemberView> { } @Override - public int compare(MemberView m1, MemberView m2) { + public int compare(MemberRow m1, MemberRow m2) { List<BusinessGroupShort> g1 = m1.getGroups(); List<BusinessGroupShort> g2 = m2.getGroups(); diff --git a/src/main/java/org/olat/group/ui/main/LeaveColumnDescriptor.java b/src/main/java/org/olat/group/ui/main/LeaveColumnDescriptor.java index e3507315c635894d57e83ccde3f53fcd63fbebc1..b1ab318fd68c43b8171123f430ab18691d310bb9 100644 --- a/src/main/java/org/olat/group/ui/main/LeaveColumnDescriptor.java +++ b/src/main/java/org/olat/group/ui/main/LeaveColumnDescriptor.java @@ -44,7 +44,7 @@ public class LeaveColumnDescriptor extends DefaultColumnDescriptor { @Override public String getAction(int row) { int sortedRow = table.getSortedRow(row); - MemberView membership = (MemberView)table.getTableDataModel() + MemberRow membership = (MemberRow)table.getTableDataModel() .getValueAt(sortedRow, MemberListTableModel.Cols.groups.ordinal()); return membership.isFullyManaged() ? null : super.getAction(row); @@ -53,7 +53,7 @@ public class LeaveColumnDescriptor extends DefaultColumnDescriptor { @Override public void renderValue(StringOutput sb, int row, Renderer renderer) { int sortedRow = table.getSortedRow(row); - MemberView membership = (MemberView)table.getTableDataModel() + MemberRow membership = (MemberRow)table.getTableDataModel() .getValueAt(sortedRow, MemberListTableModel.Cols.groups.ordinal()); if(!membership.isFullyManaged()) { diff --git a/src/main/java/org/olat/group/ui/main/MemberListTableModel.java b/src/main/java/org/olat/group/ui/main/MemberListTableModel.java index b2fa54cb7a319ef8a7a5b2f781027e2dddf8693e..08985a9bba39e2ff8950bde4aa72ed21805bdc1d 100644 --- a/src/main/java/org/olat/group/ui/main/MemberListTableModel.java +++ b/src/main/java/org/olat/group/ui/main/MemberListTableModel.java @@ -33,7 +33,7 @@ import org.olat.instantMessaging.model.Presence; * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class MemberListTableModel extends DefaultFlexiTableDataModel<MemberView> implements SortableFlexiTableDataModel<MemberView> { +public class MemberListTableModel extends DefaultFlexiTableDataModel<MemberRow> implements SortableFlexiTableDataModel<MemberRow> { private final boolean onlineStatusEnabled; @@ -45,22 +45,22 @@ public class MemberListTableModel extends DefaultFlexiTableDataModel<MemberView> @Override public void sort(SortKey orderBy) { if(orderBy != null) { - List<MemberView> views = new MemberListTableSort(orderBy, this, null).sort(); + List<MemberRow> views = new MemberListTableSort(orderBy, this, null).sort(); super.setObjects(views); } } @Override public Object getValueAt(int row, int col) { - MemberView member = getObject(row); + MemberRow member = getObject(row); return getValueAt(member, col); } @Override - public Object getValueAt(MemberView row, int col) { + public Object getValueAt(MemberRow row, int col) { if(col >= 0 && col < Cols.values().length) { switch(Cols.values()[col]) { - case username: return row.getIdentityName(); + case username: return row.getView().getIdentityName(); case firstTime: return row.getFirstTime(); case lastTime: return row.getLastTime(); case role: return row.getMembership(); @@ -95,7 +95,7 @@ public class MemberListTableModel extends DefaultFlexiTableDataModel<MemberView> } int propPos = col - AbstractMemberListController.USER_PROPS_OFFSET; - return row.getIdentityProp(propPos); + return row.getView().getIdentityProp(propPos); } @Override diff --git a/src/main/java/org/olat/group/ui/main/MemberListTableSort.java b/src/main/java/org/olat/group/ui/main/MemberListTableSort.java index 808fd2104bd96a13bd2aa7ebb24c014ac8e232d3..eda39c5d450b7df83c728f7b8a96309787649193 100644 --- a/src/main/java/org/olat/group/ui/main/MemberListTableSort.java +++ b/src/main/java/org/olat/group/ui/main/MemberListTableSort.java @@ -35,14 +35,14 @@ import org.olat.group.ui.main.MemberListTableModel.Cols; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class MemberListTableSort extends SortableFlexiTableModelDelegate<MemberView> { +public class MemberListTableSort extends SortableFlexiTableModelDelegate<MemberRow> { - public MemberListTableSort(SortKey orderBy, SortableFlexiTableDataModel<MemberView> tableModel, Locale locale) { + public MemberListTableSort(SortKey orderBy, SortableFlexiTableDataModel<MemberRow> tableModel, Locale locale) { super(orderBy, tableModel, locale); } @Override - protected void sort(List<MemberView> rows) { + protected void sort(List<MemberRow> rows) { int columnIndex = getColumnIndex(); if(columnIndex >= AbstractMemberListController.USER_PROPS_OFFSET) { super.sort(rows); @@ -62,12 +62,12 @@ public class MemberListTableSort extends SortableFlexiTableModelDelegate<MemberV } } - private static class RoleMemberViewComparator implements Comparator<MemberView> { + private static class RoleMemberViewComparator implements Comparator<MemberRow> { private final CourseMembershipComparator comparator = new CourseMembershipComparator(); @Override - public int compare(MemberView o1, MemberView o2) { + public int compare(MemberRow o1, MemberRow o2) { return comparator.compare(o1.getMembership(), o2.getMembership()); } } diff --git a/src/main/java/org/olat/group/ui/main/MemberView.java b/src/main/java/org/olat/group/ui/main/MemberRow.java similarity index 67% rename from src/main/java/org/olat/group/ui/main/MemberView.java rename to src/main/java/org/olat/group/ui/main/MemberRow.java index e7fdf035b58d46af6f064dc9ad12dd919f51228b..2e3cb8969f00ba3cebf21baf9a1df8787fdec1b7 100644 --- a/src/main/java/org/olat/group/ui/main/MemberView.java +++ b/src/main/java/org/olat/group/ui/main/MemberRow.java @@ -19,33 +19,33 @@ */ package org.olat.group.ui.main; -import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Locale; import org.olat.core.gui.components.form.flexible.elements.FormLink; -import org.olat.core.id.Identity; import org.olat.group.BusinessGroupManagedFlag; import org.olat.group.BusinessGroupShort; -import org.olat.user.UserPropertiesRow; -import org.olat.user.propertyhandlers.UserPropertyHandler; +import org.olat.group.model.MemberView; +import org.olat.modules.curriculum.CurriculumElementShort; /** * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class MemberView extends UserPropertiesRow { +public class MemberRow { private Date firstTime; private Date lastTime; - private final CourseMembership membership = new CourseMembership(); - private List<BusinessGroupShort> groups; + private String onlineStatus; private FormLink toolsLink, chatLink; - public MemberView(Identity identity, List<UserPropertyHandler> userPropertyHandlers, Locale locale) { - super(identity, userPropertyHandlers, locale); + private final MemberView view; + + public MemberRow(MemberView view) { + this.view = view; + firstTime = view.getCreationDate(); + lastTime = view.getLastModified(); } public FormLink getToolsLink() { @@ -71,40 +71,43 @@ public class MemberView extends UserPropertiesRow { public void setOnlineStatus(String onlineStatus) { this.onlineStatus = onlineStatus; } + + public MemberView getView() { + return view; + } + + public Long getIdentityKey() { + return view.getIdentityKey(); + } public CourseMembership getMembership() { - return membership; + return view.getMemberShip(); } public List<BusinessGroupShort> getGroups() { - return groups; + return view.getGroups(); } - public void setGroups(List<BusinessGroupShort> groups) { - this.groups = groups; - } - public void addGroup(BusinessGroupShort group) { - if(group == null) return; - if(groups == null) { - groups = new ArrayList<BusinessGroupShort>(3); - } - groups.add(group); + public List<CurriculumElementShort> getCurriculumElements() { + return view.getCurriculumElements(); } - + public boolean isFullyManaged() { + CourseMembership membership = getMembership(); if(membership != null && !membership.isManagedMembersRepo() && - (membership.isRepoOwner() || membership.isRepoTutor() || membership.isRepoParticipant())) { + (membership.isRepositoryEntryOwner() || membership.isRepositoryEntryCoach() || membership.isRepositoryEntryParticipant())) { return false; } - if(groups != null) { - for(BusinessGroupShort group:groups) { + if(view.getGroups() != null) { + for(BusinessGroupShort group:view.getGroups()) { if(!BusinessGroupManagedFlag.isManaged(group.getManagedFlags(), BusinessGroupManagedFlag.membersmanagement)) { return false; } } } + return true; } @@ -132,7 +135,7 @@ public class MemberView extends UserPropertiesRow { @Override public int hashCode() { - return getIdentityKey() == null ? 2878 : getIdentityKey().hashCode(); + return view.getIdentityKey() == null ? 2878 : view.getIdentityKey().hashCode(); } @Override @@ -140,9 +143,9 @@ public class MemberView extends UserPropertiesRow { if(this == obj) { return true; } - if(obj instanceof MemberView) { - MemberView member = (MemberView)obj; - return getIdentityKey() != null && getIdentityKey().equals(member.getIdentityKey()); + if(obj instanceof MemberRow) { + MemberRow member = (MemberRow)obj; + return view.getIdentityKey() != null && view.getIdentityKey().equals(member.getView().getIdentityKey()); } return false; } @@ -150,8 +153,7 @@ public class MemberView extends UserPropertiesRow { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("memberView[identityKey=").append(getIdentityKey() == null ? "" : getIdentityKey()) - .append(":login=").append(getIdentityName()).append("]"); + sb.append("memberView[identityKey=").append(view.getIdentityKey() == null ? "" : view.getIdentityKey()).append("]"); return sb.toString(); } } \ No newline at end of file diff --git a/src/main/java/org/olat/group/ui/main/SearchMembersParams.java b/src/main/java/org/olat/group/ui/main/SearchMembersParams.java index e6cbeb9fe05642dc286c1bcfd55f77ec94f311a0..67c53bd436403b54dcf535af56f1316c90561ba7 100644 --- a/src/main/java/org/olat/group/ui/main/SearchMembersParams.java +++ b/src/main/java/org/olat/group/ui/main/SearchMembersParams.java @@ -21,6 +21,7 @@ package org.olat.group.ui.main; import java.util.Map; +import org.olat.basesecurity.GroupRoles; import org.olat.core.gui.control.Event; /** @@ -30,84 +31,49 @@ import org.olat.core.gui.control.Event; public class SearchMembersParams extends Event { private static final long serialVersionUID = -8842738563007496141L; - private boolean repoOwners; - private boolean repoTutors; - private boolean repoParticipants; - private boolean groupTutors; - private boolean groupParticipants; - private boolean groupWaitingList; + private GroupRoles[] roles; private boolean pending; - private boolean repoOrigin = true; - private boolean groupOrigin = true; + private Origin origin; private String login; - private String searchString; private Map<String, String> userPropertiesSearch; public SearchMembersParams() { super("search_members"); } - public SearchMembersParams(boolean repoOwners, boolean repoTutors, boolean repoParticipants, - boolean groupTutors, boolean groupParticipants, boolean groupWaitingList, - boolean pending) { + public SearchMembersParams(boolean pending, GroupRoles... roles) { this(); - this.repoOwners = repoOwners; - this.repoTutors = repoTutors; - this.repoParticipants = repoParticipants; - this.groupTutors = groupTutors; - this.groupParticipants = groupParticipants; - this.groupWaitingList = groupWaitingList; this.pending = pending; + this.roles = roles; } - public boolean isRepoOwners() { - return repoOwners; + public GroupRoles[] getRoles() { + return roles; } - public void setRepoOwners(boolean repoOwners) { - this.repoOwners = repoOwners; + public void setRole(GroupRoles role) { + if(role == null) { + roles = null; + } else { + roles = new GroupRoles[] { role }; + } } - public boolean isRepoTutors() { - return repoTutors; + public void setRoles(GroupRoles[] roles) { + this.roles = roles; } - public void setRepoTutors(boolean repoTutors) { - this.repoTutors = repoTutors; - } - - public boolean isRepoParticipants() { - return repoParticipants; - } - - public void setRepoParticipants(boolean repoParticipants) { - this.repoParticipants = repoParticipants; - } - - public boolean isGroupTutors() { - return groupTutors; - } - - public void setGroupTutors(boolean groupTutors) { - this.groupTutors = groupTutors; - } - - public boolean isGroupParticipants() { - return groupParticipants; - } - - public void setGroupParticipants(boolean groupParticipants) { - this.groupParticipants = groupParticipants; - } - - public boolean isGroupWaitingList() { - return groupWaitingList; - } - - public void setGroupWaitingList(boolean groupWaitingList) { - this.groupWaitingList = groupWaitingList; + public boolean isRole(GroupRoles role) { + if(roles != null) { + for(GroupRoles r:roles) { + if(r == role) { + return true; + } + } + } + return false; } public boolean isPending() { @@ -118,20 +84,12 @@ public class SearchMembersParams extends Event { this.pending = pending; } - public boolean isRepoOrigin() { - return repoOrigin; - } - - public void setRepoOrigin(boolean repoOrigin) { - this.repoOrigin = repoOrigin; - } - - public boolean isGroupOrigin() { - return groupOrigin; + public Origin getOrigin() { + return origin == null ? Origin.all : origin; } - public void setGroupOrigin(boolean groupOrigin) { - this.groupOrigin = groupOrigin; + public void setOrigin(Origin origin) { + this.origin = origin; } public String getLogin() { @@ -142,14 +100,6 @@ public class SearchMembersParams extends Event { this.login = login; } - public String getSearchString() { - return searchString; - } - - public void setSearchString(String searchString) { - this.searchString = searchString; - } - public Map<String, String> getUserPropertiesSearch() { return userPropertiesSearch; } @@ -157,4 +107,11 @@ public class SearchMembersParams extends Event { public void setUserPropertiesSearch(Map<String, String> userPropertiesSearch) { this.userPropertiesSearch = userPropertiesSearch; } + + public enum Origin { + all, + repositoryEntry, + businessGroup, + curriculum + } } \ No newline at end of file diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties index 64ce196f7d2218eb0309bfc69893552d06f0da04..70b11c27d07ff94dcc5beae3d080f94c25607ba0 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties @@ -156,7 +156,9 @@ edit.member.groups=Gruppenmitgliedschaften import.member=Mitglieder hinzuf\u00FCgen - +role.curriculum.participant=Curriculumteilnehmer +role.curriculum.coach=Curriculumbetreuers +role.curriculum.owner=Curriculumkursbesitzer role.group.tutor=Gruppenbetreuer role.group.participant=Gruppenteilnehmer role.group.waiting=Warteliste diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_en.properties index 26dd51cca070c0cd1f37d85290cfd2289a42364d..bd56d14521591305bb41c0bd8f3ebb8ac28fa126 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_en.properties @@ -99,6 +99,9 @@ remove.send.mail.label=Send E-mail request.leaving.body=Dear group coach<br /><br />Please remove me from this group.<br /><br />Best regards<br />{3} {4}<br /><br />Group name\: {0}<br />Group ID\: {1}<br />Group used in course\: {2} request.leaving.subject=Request to leave group "{0}" (ID {1}) reservation.coach=as coach +role.curriculum.coach=Curriculum coach +role.curriculum.owner=Curriculum course owner +role.curricullum.participant=Curriculum member role.group.participant=Group member role.group.tutor=Group coach role.group.waiting=Waiting list diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumElementShort.java b/src/main/java/org/olat/modules/curriculum/CurriculumElementShort.java new file mode 100644 index 0000000000000000000000000000000000000000..86c61b8167af1e4f81ce0ab6da94387ec04802d0 --- /dev/null +++ b/src/main/java/org/olat/modules/curriculum/CurriculumElementShort.java @@ -0,0 +1,34 @@ +/** + * <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> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.curriculum; + +/** + * + * Initial date: 6 juin 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface CurriculumElementShort extends CurriculumElementRef { + + public String getDisplayName(); + + public CurriculumElementManagedFlag[] getManagedFlags(); + +} diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumRoles.java b/src/main/java/org/olat/modules/curriculum/CurriculumRoles.java index 6dca311f822bd75660d682e12f30b32521c58bda..f7ec99039f1669b7333fdcb93ecb7d786d569072 100644 --- a/src/main/java/org/olat/modules/curriculum/CurriculumRoles.java +++ b/src/main/java/org/olat/modules/curriculum/CurriculumRoles.java @@ -19,6 +19,8 @@ */ package org.olat.modules.curriculum; +import org.olat.core.util.StringHelper; + /** * * Initial date: 9 mai 2018<br> @@ -27,6 +29,19 @@ package org.olat.modules.curriculum; */ public enum CurriculumRoles { - supervisor, - + curriculummanager, + owner, //same as GroupRoles + coach, //same as GroupRoles + participant; //same as GroupRoles + + public static final boolean isValueOf(String val) { + if(StringHelper.containsNonWhitespace(val)) { + for(CurriculumRoles role:values()) { + if(role.name().equals(val)) { + return true; + } + } + } + return false; + } } diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumService.java b/src/main/java/org/olat/modules/curriculum/CurriculumService.java index 2ea8768b7db82ee251d86859d442cb6861c3b757..754229852495cb305f32aa5ea307705d83524bb7 100644 --- a/src/main/java/org/olat/modules/curriculum/CurriculumService.java +++ b/src/main/java/org/olat/modules/curriculum/CurriculumService.java @@ -153,6 +153,15 @@ public interface CurriculumService { */ public List<CurriculumElementMember> getMembers(CurriculumElement element); + /** + * The list of members of the specified curriculum element with the specified role. + * + * @param element The curriculum element + * @param role The role + * @return The list of memberships + */ + public List<Identity> getMembersIdentity(CurriculumElementRef element, CurriculumRoles role); + /** * Add a member with the specified role to the curriculum element. The * inheritance mode of the membership is per default "none". @@ -171,6 +180,15 @@ public interface CurriculumService { */ public void removeMember(CurriculumElement element, IdentityRef member); + /** + * Remove the membership of a user with the specified role. + * + * @param element The curriculum element + * @param member The identity which loose the membership + * @param role The role + */ + public void removeMember(CurriculumElement element, IdentityRef member, CurriculumRoles role); + /** * The all list of repository entries hold by the specified curriculum element. * @@ -179,6 +197,16 @@ public interface CurriculumService { */ public List<RepositoryEntry> getRepositoryEntries(CurriculumElementRef element); + /** + * Check if the repository entry is already in relation with the specified + * curriculum element. + * + * @param element The curriculum element + * @param entry The repository entry + * @return True if the repository entry and curriculum element share a group + */ + public boolean hasRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry); + /** * This will add a relation between the curriculum element and the repository * entry and it will add the base group of the curriculum to the set of groups @@ -191,6 +219,9 @@ public interface CurriculumService { */ public void addRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry, boolean master); + + public void removeRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry); + public List<CurriculumElementRepositoryEntryViews> getCurriculumElements(Identity identity, Roles roles, CurriculumRef curriculum); diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java index b255ac824284e69d19a762b785a4ff677ee6023f..180ef74fbb38de99d0cb481758bf9e753b08807c 100644 --- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java +++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java @@ -30,6 +30,7 @@ import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.PersistenceHelper; import org.olat.core.id.Organisation; import org.olat.core.id.OrganisationRef; +import org.olat.core.util.StringHelper; import org.olat.modules.curriculum.Curriculum; import org.olat.modules.curriculum.model.CurriculumImpl; import org.olat.modules.curriculum.model.CurriculumSearchParameters; @@ -88,6 +89,25 @@ public class CurriculumDAO { where = PersistenceHelper.appendAnd(sb, where); sb.append(" cur.organisation.key in (:organisationKeys)"); } + + Long key = null; + String ref = null; + String fuzzyRef = null; + if(StringHelper.containsNonWhitespace(params.getSearchString())) { + ref = params.getSearchString(); + fuzzyRef = PersistenceHelper.makeFuzzyQueryString(ref); + + where = PersistenceHelper.appendAnd(sb, where); + sb.append(" (cur.externalId=:ref or "); + PersistenceHelper.appendFuzzyLike(sb, "cur.displayName", "fuzzyRef", dbInstance.getDbVendor()); + sb.append(" or "); + PersistenceHelper.appendFuzzyLike(sb, "cur.identifier", "fuzzyRef", dbInstance.getDbVendor()); + if(StringHelper.isLong(ref)) { + key = Long.valueOf(ref); + sb.append(" or cur.key=:curriculumKey"); + } + sb.append(")"); + } TypedQuery<Curriculum> query = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), Curriculum.class); @@ -96,6 +116,15 @@ public class CurriculumDAO { .stream().map(OrganisationRef::getKey).collect(Collectors.toList()); query.setParameter("organisationKeys", organisationKeys); } + if(key != null) { + query.setParameter("curriculumKey", key); + } + if(ref != null) { + query.setParameter("ref", ref); + } + if(fuzzyRef != null) { + query.setParameter("fuzzyRef", fuzzyRef); + } return query.getResultList(); } diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java index 328ebc6fe7507e30cf247db885235602730dc7ae..1d57622bfa8adb85dec12c805a3f89161919adff 100644 --- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java +++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java @@ -197,6 +197,7 @@ public class CurriculumElementDAO { .append(" inner join el.group baseGroup") .append(" inner join baseGroup.members membership") .append(" inner join membership.identity ident") + .append(" inner join fetch ident.user identUser") .append(" where el.key=:elementKey"); List<Object[]> objects = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), Object[].class) @@ -216,6 +217,21 @@ public class CurriculumElementDAO { return members; } + public List<Identity> getMembersIdentity(CurriculumElementRef element, String role) { + StringBuilder sb = new StringBuilder(256); + sb.append("select ident from curriculumelement el") + .append(" inner join el.group baseGroup") + .append(" inner join baseGroup.members membership") + .append(" inner join membership.identity ident") + .append(" inner join fetch ident.user identUser") + .append(" where el.key=:elementKey and membership.role=:role"); + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Identity.class) + .setParameter("elementKey", element.getKey()) + .setParameter("role", role) + .getResultList(); + } + private static class PathMaterializedPathLengthComparator implements Comparator<CurriculumElement> { @Override public int compare(CurriculumElement c1, CurriculumElement c2) { diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java index bad5f5dc2da52c9325cc8e43b0a573d92678b87c..b69f64fb796ea0e9cf79acda667e1d1f0884c28f 100644 --- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java +++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java @@ -59,6 +59,25 @@ public class CurriculumRepositoryEntryRelationDAO { return relation; } + public List<CurriculumRepositoryEntryRelation> getRelations(RepositoryEntryRef entry, CurriculumElementRef element) { + StringBuilder sb = new StringBuilder(256); + sb.append("select rel from repoentrytocurriculumelement as rel") + .append(" where rel.entry.key=:repoKey and rel.curriculumElement.key=:elementKey"); + + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), CurriculumRepositoryEntryRelation.class) + .setParameter("repoKey", entry.getKey()) + .setParameter("elementKey", element.getKey()) + .getResultList(); + } + + public void deleteRelation(RepositoryEntryRef entry, CurriculumElementRef element) { + List<CurriculumRepositoryEntryRelation> relations = getRelations(entry, element); + for(CurriculumRepositoryEntryRelation relation:relations) { + dbInstance.getCurrentEntityManager().remove(relation); + } + } + public List<CurriculumElement> getCurriculumElements(RepositoryEntryRef entry) { StringBuilder sb = new StringBuilder(256); sb.append("select el from curriculumelement as el") diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java index 27a2854da3d7d227940ab3859b6f8d3b10c01972..7db12eb009bb52d1004975940fabb69cc1fdc67a 100644 --- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java +++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java @@ -198,6 +198,11 @@ public class CurriculumServiceImpl implements CurriculumService { public List<CurriculumElementMember> getMembers(CurriculumElement element) { return curriculumElementDao.getMembers(element); } + + @Override + public List<Identity> getMembersIdentity(CurriculumElementRef element, CurriculumRoles role) { + return curriculumElementDao.getMembersIdentity(element, role.name()); + } @Override public void addMember(CurriculumElement element, Identity member, CurriculumRoles role) { @@ -211,6 +216,11 @@ public class CurriculumServiceImpl implements CurriculumService { groupDao.removeMembership(element.getGroup(), member); } + @Override + public void removeMember(CurriculumElement element, IdentityRef member, CurriculumRoles role) { + groupDao.removeMembership(element.getGroup(), member, role.name()); + } + @Override public List<RepositoryEntry> getRepositoryEntries(CurriculumElementRef element) { return curriculumRepositoryEntryRelationDao.getRepositoryEntries(element); @@ -223,6 +233,17 @@ public class CurriculumServiceImpl implements CurriculumService { curriculumRepositoryEntryRelationDao.createRelation(repoEntry, element, master); } + @Override + public boolean hasRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry) { + return repositoryEntryRelationDao.hasRelation(element.getGroup(), entry); + } + + @Override + public void removeRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry) { + repositoryEntryRelationDao.removeRelation(element.getGroup(), entry); + curriculumRepositoryEntryRelationDao.deleteRelation(entry, element); + } + @Override public List<CurriculumElementRepositoryEntryViews> getCurriculumElements(Identity identity, Roles roles, CurriculumRef curriculum) { if(curriculum == null) return Collections.emptyList(); diff --git a/src/main/java/org/olat/modules/curriculum/model/CurriculumSearchParameters.java b/src/main/java/org/olat/modules/curriculum/model/CurriculumSearchParameters.java index 5f55323df0465b474cf8e313be40dad8a4a39ee1..4367f160272ee2d7c88c800acc26654dbe8f689b 100644 --- a/src/main/java/org/olat/modules/curriculum/model/CurriculumSearchParameters.java +++ b/src/main/java/org/olat/modules/curriculum/model/CurriculumSearchParameters.java @@ -32,6 +32,7 @@ import org.olat.core.id.OrganisationRef; */ public class CurriculumSearchParameters { + private String searchString; private List<OrganisationRef> organisations; public List<OrganisationRef> getOrganisations() { @@ -44,7 +45,12 @@ public class CurriculumSearchParameters { public void setOrganisations(List<OrganisationRef> organisations) { this.organisations = organisations; } - - + public String getSearchString() { + return searchString; + } + + public void setSearchString(String searchString) { + this.searchString = searchString; + } } diff --git a/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementMemberVO.java b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementMemberVO.java new file mode 100644 index 0000000000000000000000000000000000000000..c81bb22ddf723c0675493a9a437e088200a6b491 --- /dev/null +++ b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementMemberVO.java @@ -0,0 +1,82 @@ +/** + * <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> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.curriculum.restapi; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import org.olat.modules.curriculum.model.CurriculumElementMember; + +/** + * + * Initial date: 4 juin 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "curriculumElementMemberVO") +public class CurriculumElementMemberVO { + + private Long identityKey; + private String role; + private String inheritanceMode; + + public CurriculumElementMemberVO() { + // + } + + public static final CurriculumElementMemberVO valueOf(CurriculumElementMember membership) { + CurriculumElementMemberVO vo = new CurriculumElementMemberVO(); + vo.setIdentityKey(membership.getIdentity().getKey()); + vo.setRole(membership.getRole()); + if(membership.getInheritanceMode() != null) { + vo.setInheritanceMode(membership.getInheritanceMode().name()); + } + return vo; + } + + public Long getIdentityKey() { + return identityKey; + } + + public void setIdentityKey(Long identityKey) { + this.identityKey = identityKey; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public String getInheritanceMode() { + return inheritanceMode; + } + + public void setInheritanceMode(String inheritanceMode) { + this.inheritanceMode = inheritanceMode; + } + + + +} diff --git a/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java index 4dbbfb1a342cb392b1818e4aa797324a645c03b0..3ff22a8cd14ae1833a7f94122a06c34a38c18919 100644 --- a/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java +++ b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java @@ -24,27 +24,38 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import org.olat.basesecurity.BaseSecurity; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; import org.olat.modules.curriculum.Curriculum; import org.olat.modules.curriculum.CurriculumElement; import org.olat.modules.curriculum.CurriculumElementManagedFlag; import org.olat.modules.curriculum.CurriculumElementType; +import org.olat.modules.curriculum.CurriculumRoles; import org.olat.modules.curriculum.CurriculumService; +import org.olat.modules.curriculum.model.CurriculumElementMember; import org.olat.modules.curriculum.model.CurriculumElementRefImpl; import org.olat.modules.curriculum.model.CurriculumElementTypeRefImpl; +import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryService; +import org.olat.user.restapi.UserVO; +import org.olat.user.restapi.UserVOFactory; +import org.springframework.beans.factory.annotation.Autowired; /** * The security checks are done by the CurriculumsWebService. @@ -55,10 +66,20 @@ import org.olat.modules.curriculum.model.CurriculumElementTypeRefImpl; */ public class CurriculumElementsWebService { + @Autowired + private DB dbInstance; + @Autowired + private BaseSecurity securityManager; + @Autowired + private CurriculumService curriculumService; + @Autowired + private RepositoryService repositoryService; + private final Curriculum curriculum; public CurriculumElementsWebService(Curriculum curriculum) { this.curriculum = curriculum; + CoreSpringFactory.autowireObject(this); } /** @@ -76,7 +97,6 @@ public class CurriculumElementsWebService { @GET @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response getCurriculumElements() { - CurriculumService curriculumService = CoreSpringFactory.getImpl(CurriculumService.class); List<CurriculumElement> elements = curriculumService.getCurriculumElements(curriculum); List<CurriculumElementVO> voes = new ArrayList<>(elements.size()); for(CurriculumElement element:elements) { @@ -101,7 +121,6 @@ public class CurriculumElementsWebService { @Path("{curriculumElementKey}") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response getCurriculumElement(@PathParam("curriculumElementKey") Long curriculumElementKey, @Context HttpServletRequest httpRequest) { - CurriculumService curriculumService = CoreSpringFactory.getImpl(CurriculumService.class); CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey)); if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) { return Response.serverError().status(Status.UNAUTHORIZED).build(); @@ -190,8 +209,6 @@ public class CurriculumElementsWebService { private CurriculumElement saveCurriculumElement(CurriculumElementVO curriculumElement) { - CurriculumService curriculumService = CoreSpringFactory.getImpl(CurriculumService.class); - CurriculumElement elementToSave = null; CurriculumElementType type = null; if(curriculumElement.getCurriculumElementTypeKey() != null) { @@ -229,15 +246,582 @@ public class CurriculumElementsWebService { CurriculumElement savedElement = curriculumService.updateCurriculumElement(elementToSave); if(move) { curriculumService.moveCurriculumElement(savedElement, parentElement); - CoreSpringFactory.getImpl(DB.class).commit(); + dbInstance.commit(); savedElement = curriculumService.getCurriculumElement(savedElement); } return savedElement; } - public void checkCurriculum(CurriculumElement element) { + private void checkCurriculum(CurriculumElement element) { if(element.getCurriculum() != null && !element.getCurriculum().getKey().equals(curriculum.getKey())) { throw new WebApplicationException(Response.serverError().status(Status.CONFLICT).build()); } } + + /** + * Add a relation between a repository entry and a curriculum element. + * + * @response.representation.200.doc The relation was added + * @response.representation.304.doc There is already a relation, nothing changed + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the repository entry was not found + * @param curriculumElementKey The curriculum element + * @param repositoryEntryKey The repository entry + * @return Nothing + */ + @PUT + @Path("{curriculumElementKey}/entries/{repositoryEntryKey}") + public Response addRepositoryEntryToElement(@PathParam("curriculumElementKey") Long curriculumElementKey, + @PathParam("repositoryEntryKey") Long repositoryEntryKey) { + CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey)); + if(curriculumElement == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + RepositoryEntry entry = repositoryService.loadByKey(repositoryEntryKey); + if(entry == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + if(!curriculumService.hasRepositoryEntry(curriculumElement, entry)) { + curriculumService.addRepositoryEntry(curriculumElement, entry, false); + return Response.ok().build(); + } + return Response.ok().status(Status.NOT_MODIFIED).build(); + } + + + /** + * Remove a relation between a curriculum element and a repository entry. + * + * @response.representation.200.doc The relation was successfully removed. + * @response.representation.304.doc There is no relation to remove + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the repository entry was not found + * @param curriculumElementKey The curriculum element + * @param repositoryEntryKey The repository entry + * @return Nothing + */ + @DELETE + @Path("{curriculumElementKey}/entries/{repositoryEntryKey}") + public Response removeRepositoryEntryToElement(@PathParam("curriculumElementKey") Long curriculumElementKey, + @PathParam("repositoryEntryKey") Long repositoryEntryKey) { + CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey)); + if(curriculumElement == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + RepositoryEntry entry = repositoryService.loadByKey(repositoryEntryKey); + if(entry == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + if(curriculumService.hasRepositoryEntry(curriculumElement, entry)) { + curriculumService.removeRepositoryEntry(curriculumElement, entry); + return Response.ok().build(); + } + return Response.ok().status(Status.NOT_MODIFIED).build(); + } + + /** + * Get the memberships informations of the specified curriculum element. + * + * @response.representation.200.qname {http://www.example.com}curriculumElementMemberVO + * @response.representation.200.mediaType application/xml, application/json + * @response.representation.200.doc The curriculum element membership + * @response.representation.200.example {@link org.olat.modules.curriculum.restapi.Examples#SAMPLE_CURRICULUMELEMENTMEMBERVO} + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @param curriculumElementKey The curriculum element primary key + * @param httpRequest The HTTP request + * @return The curriculum element + */ + @GET + @Path("{curriculumElementKey}/members") + public Response getMembers(@PathParam("curriculumElementKey") Long curriculumElementKey) { + CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey)); + if(curriculumElement == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + + List<CurriculumElementMember> members = curriculumService.getMembers(curriculumElement); + List<CurriculumElementMemberVO> voList = new ArrayList<>(members.size()); + for(CurriculumElementMember member:members) { + voList.add(CurriculumElementMemberVO.valueOf(member)); + } + return Response.ok(voList.toArray(new CurriculumElementMemberVO[voList.size()])).build(); + } + + /** + * Get all members of the specified curriculum element. A query parameter can + * specify the role of them. + * + * @response.representation.200.qname {http://www.example.com}userVO + * @response.representation.200.mediaType application/xml, application/json + * @response.representation.200.doc The array of authors + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The course not found + * @param httpRequest The HTTP request + * @return It returns an array of <code>UserVO</code> + */ + @GET + @Path("{curriculumElementKey}/users") + public Response getUsers(@PathParam("curriculumElementKey") Long curriculumElementKey, @QueryParam("role") String role) { + CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey)); + if(curriculumElement == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + if(role != null && !CurriculumRoles.isValueOf(role)) { + return Response.serverError().status(Status.CONFLICT).build(); + } + + List<Identity> members = curriculumService.getMembersIdentity(curriculumElement, CurriculumRoles.valueOf(role)); + List<UserVO> voList = new ArrayList<>(members.size()); + for(Identity member:members) { + voList.add(UserVOFactory.get(member)); + } + return Response.ok(voList.toArray(new UserVO[voList.size()])).build(); + } + + /** + * Add a membership to the specified curriculum element. + * + * @response.representation.qname {http://www.example.com}curriculumElementMemberVO + * @response.representation.mediaType application/xml, application/json + * @response.representation.doc The curriculum element membership to persist + * @response.representation.example {@link org.olat.modules.curriculum.restapi.Examples#SAMPLE_CURRICULUMELEMENTMEMBERVO} + * @response.representation.200.doc The membership was persisted + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @response.representation.409.doc The role is not allowed + * @param curriculumElementKey The curriculum element primary key + * @param membership The membership informations + * @return Nothing + */ + @PUT + @Path("{curriculumElementKey}/members") + public Response putMembers(@PathParam("curriculumElementKey") Long curriculumElementKey, + CurriculumElementMemberVO membership) { + CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey)); + if(curriculumElement == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + Identity identity = securityManager.loadIdentityByKey(membership.getIdentityKey()); + if(identity == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + String role = membership.getRole(); + if(!CurriculumRoles.isValueOf(role)) { + return Response.serverError().status(Status.CONFLICT).build(); + } + curriculumService.addMember(curriculumElement, identity, CurriculumRoles.valueOf(role)); + return Response.ok().build(); + } + + /** + * Remove all memberships of the identity from the specified curriculum element. + * + * @response.representation.200.doc The membership was removed + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @param curriculumElementKey The curriculum element primary key + * @param identityKey The member to remove + * @return Nothing + */ + @DELETE + @Path("{curriculumElementKey}/members/{identityKey}") + public Response deleteMembers(@PathParam("curriculumElementKey") Long curriculumElementKey, + @PathParam("identityKey") Long identityKey) { + CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey)); + if(curriculumElement == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + Identity identity = securityManager.loadIdentityByKey(identityKey); + if(identity == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + curriculumService.removeMember(curriculumElement, identity); + return Response.ok().build(); + } + + /** + * Get all participants of the specified curriculum element. + * + * @response.representation.200.qname {http://www.example.com}userVO + * @response.representation.200.mediaType application/xml, application/json + * @response.representation.200.doc The array of participants + * @response.representation.200.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes} + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element not found + * @param httpRequest The HTTP request + * @return It returns an array of <code>UserVO</code> + */ + @GET + @Path("{curriculumElementKey}/participants") + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response getParticipants(@PathParam("curriculumElementKey") Long curriculumElementKey) { + return getMembers(curriculumElementKey, CurriculumRoles.participant); + } + + /** + * Get all coaches of the specified curriculum element. + * + * @response.representation.200.qname {http://www.example.com}userVO + * @response.representation.200.mediaType application/xml, application/json + * @response.representation.200.doc The array of coaches + * @response.representation.200.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes} + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element not found + * @param httpRequest The HTTP request + * @return It returns an array of <code>UserVO</code> + */ + @GET + @Path("{curriculumElementKey}/coaches") + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response getCoaches(@PathParam("curriculumElementKey") Long curriculumElementKey) { + return getMembers(curriculumElementKey, CurriculumRoles.coach); + } + + /** + * Get all owners of the specified curriculum element. + * + * @response.representation.200.qname {http://www.example.com}userVO + * @response.representation.200.mediaType application/xml, application/json + * @response.representation.200.doc The array of coaches + * @response.representation.200.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes} + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element not found + * @param httpRequest The HTTP request + * @return It returns an array of <code>UserVO</code> + */ + @GET + @Path("{curriculumElementKey}/owners") + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response getOwners(@PathParam("curriculumElementKey") Long curriculumElementKey) { + return getMembers(curriculumElementKey, CurriculumRoles.owner); + } + + /** + * Get all curriculum managers of the specified curriculum element. + * + * @response.representation.200.qname {http://www.example.com}userVO + * @response.representation.200.mediaType application/xml, application/json + * @response.representation.200.doc The array of coaches + * @response.representation.200.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes} + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element not found + * @param httpRequest The HTTP request + * @return It returns an array of <code>UserVO</code> + */ + @GET + @Path("{curriculumElementKey}/curriculummanagers") + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response getCurriculumManagers(@PathParam("curriculumElementKey") Long curriculumElementKey) { + return getMembers(curriculumElementKey, CurriculumRoles.curriculummanager); + } + + private Response getMembers(Long curriculumElementKey, CurriculumRoles role) { + CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey)); + if(curriculumElement == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + List<Identity> members = curriculumService.getMembersIdentity(curriculumElement, role); + List<UserVO> voList = new ArrayList<>(members.size()); + for(Identity member:members) { + voList.add(UserVOFactory.get(member)); + } + return Response.ok(voList.toArray(new UserVO[voList.size()])).build(); + } + + /** + * Make the specified user a participant of the curriculum element. + * + * @response.representation.200.doc The membership was added + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @param curriculumElementKey The curriculum element primary key + * @param identityKey The member to make a participant of + * @return Nothing + */ + @PUT + @Path("{curriculumElementKey}/participants/{identityKey}") + public Response putParticipant(@PathParam("curriculumElementKey") Long curriculumElementKey, @PathParam("identityKey") Long identityKey) { + return putMember(curriculumElementKey, identityKey, CurriculumRoles.participant); + } + + /** + * Make the specified user a coach of the curriculum element. + * + * @response.representation.200.doc The membership was added + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @param curriculumElementKey The curriculum element primary key + * @param identityKey The member to make a coach of + * @return Nothing + */ + @PUT + @Path("{curriculumElementKey}/coaches/{identityKey}") + public Response putCoach(@PathParam("curriculumElementKey") Long curriculumElementKey, @PathParam("identityKey") Long identityKey) { + return putMember(curriculumElementKey, identityKey, CurriculumRoles.coach); + } + + /** + * Make the specified user a course owner of the curriculum element. + * + * @response.representation.200.doc The membership was added + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @param curriculumElementKey The curriculum element primary key + * @param identityKey The member to make a course owner of + * @return Nothing + */ + @PUT + @Path("{curriculumElementKey}/owners/{identityKey}") + public Response putOwner(@PathParam("curriculumElementKey") Long curriculumElementKey, @PathParam("identityKey") Long identityKey) { + return putMember(curriculumElementKey, identityKey, CurriculumRoles.owner); + } + + /** + * Make the specified user a curricullum manager of the curriculum element. + * + * @response.representation.200.doc The membership was added + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @param curriculumElementKey The curriculum element primary key + * @param identityKey The member to make a curriculum manager of + * @return Nothing + */ + @PUT + @Path("{curriculumElementKey}/curriculummanagers/{identityKey}") + public Response putCurriculumManager(@PathParam("curriculumElementKey") Long curriculumElementKey, @PathParam("identityKey") Long identityKey) { + return putMember(curriculumElementKey, identityKey, CurriculumRoles.curriculummanager); + } + + private Response putMember(Long curriculumElementKey, Long identityKey, CurriculumRoles role) { + CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey)); + if(curriculumElement == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + Identity identity = securityManager.loadIdentityByKey(identityKey); + if(identity == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + curriculumService.addMember(curriculumElement, identity, role); + return Response.ok().build(); + } + + /** + * Make the array of users participant of the specified curriculum element. + * + * @response.representation.qname {http://www.example.com}userVO + * @response.representation.mediaType application/xml, application/json + * @response.representation.doc The curriculum element membership to persist + * @response.representation.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes} + * @response.representation.200.doc The memberships was persisted + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @response.representation.409.doc The role is not allowed + * @param curriculumElementKey The curriculum element primary key + * @param participants The future participants + * @return Nothing + */ + @PUT + @Path("{curriculumElementKey}/participants") + @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response putParticipants(@PathParam("curriculumElementKey") Long curriculumElementKey, UserVO[] participants) { + return putMembers(curriculumElementKey, participants, CurriculumRoles.participant); + } + + /** + * Make the array of users coach of the specified curriculum element. + * + * @response.representation.qname {http://www.example.com}userVO + * @response.representation.mediaType application/xml, application/json + * @response.representation.doc The curriculum element membership to persist + * @response.representation.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes} + * @response.representation.200.doc The memberships was persisted + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @response.representation.409.doc The role is not allowed + * @param curriculumElementKey The curriculum element primary key + * @param participants The future coaches + * @return Nothing + */ + @PUT + @Path("{curriculumElementKey}/coaches") + @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response putCoaches(@PathParam("curriculumElementKey") Long curriculumElementKey, UserVO[] coaches) { + return putMembers(curriculumElementKey, coaches, CurriculumRoles.coach); + } + + /** + * Make the array of users course owner of the specified curriculum element. + * + * @response.representation.qname {http://www.example.com}userVO + * @response.representation.mediaType application/xml, application/json + * @response.representation.doc The curriculum element membership to persist + * @response.representation.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes} + * @response.representation.200.doc The memberships was persisted + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @response.representation.409.doc The role is not allowed + * @param curriculumElementKey The curriculum element primary key + * @param participants The future course owners + * @return Nothing + */ + @PUT + @Path("{curriculumElementKey}/owners") + @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response putOwners(@PathParam("curriculumElementKey") Long curriculumElementKey, UserVO[] coaches) { + return putMembers(curriculumElementKey, coaches, CurriculumRoles.owner); + } + + /** + * Make the array of users curriculum managers of the specified curriculum element. + * + * @response.representation.qname {http://www.example.com}userVO + * @response.representation.mediaType application/xml, application/json + * @response.representation.doc The curriculum element membership to persist + * @response.representation.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes} + * @response.representation.200.doc The memberships was persisted + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @response.representation.409.doc The role is not allowed + * @param curriculumElementKey The curriculum element primary key + * @param participants The future curriculum manages + * @return Nothing + */ + @PUT + @Path("{curriculumElementKey}/curriculummanagers") + @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response putCurriculumManagers(@PathParam("curriculumElementKey") Long curriculumElementKey, UserVO[] coaches) { + return putMembers(curriculumElementKey, coaches, CurriculumRoles.curriculummanager); + } + + private Response putMembers(Long curriculumElementKey, UserVO[] members, CurriculumRoles role) { + CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey)); + if(curriculumElement == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + + for(UserVO member:members) { + Identity identity = securityManager.loadIdentityByKey(member.getKey()); + if(identity != null) { + curriculumService.addMember(curriculumElement, identity, role); + } + } + return Response.ok().build(); + } + + /** + * Remove the participant membership of the identity from the specified curriculum element. + * + * @response.representation.200.doc The membership was removed + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @param curriculumElementKey The curriculum element primary key + * @param identityKey The member to remove + * @return Nothing + */ + @DELETE + @Path("{curriculumElementKey}/participants/{identityKey}") + public Response deleteParticipant(@PathParam("curriculumElementKey") Long curriculumElementKey, + @PathParam("identityKey") Long identityKey) { + return deleteMember(curriculumElementKey, identityKey, CurriculumRoles.participant); + } + + /** + * Remove the coach membership of the identity from the specified curriculum element. + * + * @response.representation.200.doc The membership was removed + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @param curriculumElementKey The curriculum element primary key + * @param identityKey The member to remove + * @return Nothing + */ + @DELETE + @Path("{curriculumElementKey}/coaches/{identityKey}") + public Response deleteCoach(@PathParam("curriculumElementKey") Long curriculumElementKey, + @PathParam("identityKey") Long identityKey) { + return deleteMember(curriculumElementKey, identityKey, CurriculumRoles.coach); + } + + /** + * Remove the owner membership of the identity from the specified curriculum element. + * + * @response.representation.200.doc The membership was removed + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @param curriculumElementKey The curriculum element primary key + * @param identityKey The member to remove + * @return Nothing + */ + @DELETE + @Path("{curriculumElementKey}/owners/{identityKey}") + public Response deleteOwner(@PathParam("curriculumElementKey") Long curriculumElementKey, + @PathParam("identityKey") Long identityKey) { + return deleteMember(curriculumElementKey, identityKey, CurriculumRoles.owner); + } + + /** + * Remove the curriculum manager membership of the identity from the specified curriculum element. + * + * @response.representation.200.doc The membership was removed + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @param curriculumElementKey The curriculum element primary key + * @param identityKey The member to remove + * @return Nothing + */ + @DELETE + @Path("{curriculumElementKey}/curriculummanagers/{identityKey}") + public Response deleteCurriculumManager(@PathParam("curriculumElementKey") Long curriculumElementKey, + @PathParam("identityKey") Long identityKey) { + return deleteMember(curriculumElementKey, identityKey, CurriculumRoles.curriculummanager); + } + + private Response deleteMember(Long curriculumElementKey, Long identityKey, CurriculumRoles role) { + CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey)); + if(curriculumElement == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + Identity identity = securityManager.loadIdentityByKey(identityKey); + if(identity == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + curriculumService.removeMember(curriculumElement, identity, role); + return Response.ok().build(); + } } diff --git a/src/main/java/org/olat/modules/curriculum/restapi/CurriculumsWebService.java b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumsWebService.java index a8371cb259276b3da52e2b4bbe1c92c1ba11525a..e649932c395a0b5767b7e2ae96dc75d1d67cc4a9 100644 --- a/src/main/java/org/olat/modules/curriculum/restapi/CurriculumsWebService.java +++ b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumsWebService.java @@ -214,6 +214,9 @@ public class CurriculumsWebService { @Context HttpServletRequest httpRequest) { CurriculumService curriculumService = CoreSpringFactory.getImpl(CurriculumService.class); Curriculum curriculum = curriculumService.getCurriculum(new CurriculumRefImpl(curriculumKey)); + if(curriculum == null) { + throw new WebApplicationException(Status.NOT_FOUND); + } allowedOrganisation(curriculum.getOrganisation(), getRoles(httpRequest)); return new CurriculumElementsWebService(curriculum); } diff --git a/src/main/java/org/olat/modules/curriculum/restapi/Examples.java b/src/main/java/org/olat/modules/curriculum/restapi/Examples.java index 3be4ab6fed98ba5a9640b8a7a04f1d2f0059f644..4ff2e338ff34a87820a03dfef33fcc0e34a7a81d 100644 --- a/src/main/java/org/olat/modules/curriculum/restapi/Examples.java +++ b/src/main/java/org/olat/modules/curriculum/restapi/Examples.java @@ -35,6 +35,8 @@ public class Examples { public static final CurriculumElementTypeVO SAMPLE_CURRICULUMELEMENTTYPEVO = new CurriculumElementTypeVO(); + public static final CurriculumElementMemberVO SAMPLE_CURRICULUMELEMENTMEMBERVO = new CurriculumElementMemberVO(); + static { SAMPLE_CURRICULUMVO.setKey(2l); SAMPLE_CURRICULUMVO.setDisplayName("Dipl. engineer"); @@ -64,5 +66,9 @@ public class Examples { SAMPLE_CURRICULUMELEMENTTYPEVO.setExternalId("CET-1001"); SAMPLE_CURRICULUMELEMENTTYPEVO.setDescription("This is the description of a type"); SAMPLE_CURRICULUMELEMENTTYPEVO.setManagedFlagsString("displayName"); + + SAMPLE_CURRICULUMELEMENTMEMBERVO.setIdentityKey(111l); + SAMPLE_CURRICULUMELEMENTMEMBERVO.setInheritanceMode("none"); + SAMPLE_CURRICULUMELEMENTMEMBERVO.setRole("participant"); } } \ No newline at end of file diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementUserManagementController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementUserManagementController.java index 10c764bcf21342a938edaa6c42866e916b6f354b..1ce1db9398c1e23f48b03c8c70aef6c1cb404f0c 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementUserManagementController.java +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementUserManagementController.java @@ -108,8 +108,8 @@ public class CurriculumElementUserManagementController extends FormBasicControll membersManaged = CurriculumElementManagedFlag.isManaged(curriculumElement, CurriculumElementManagedFlag.members); - initForm(ureq); + loadModel(true); } @Override diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java index 7f13273be280fe580b6723e3e37af9339c26104a..312937f8b86e99b7a8c3af1d5f7b84f33c51fa90 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java @@ -83,7 +83,7 @@ public class CurriculumListController extends FormBasicController implements Act toolsCol.setAlwaysVisible(true); columnsModel.addFlexiColumnModel(toolsCol); - tableModel = new CurriculumManagerDataModel(columnsModel); + tableModel = new CurriculumManagerDataModel(columnsModel, getLocale()); tableEl = uifactory.addTableElement(getWindowControl(), "table", tableModel, 20, false, getTranslator(), formLayout); tableEl.setCustomizeColumns(true); tableEl.setEmtpyTableMessageKey("table.curriculum.empty"); diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java index ef489937689919242eaf27d795dc43462eda4e71..7acfbbfc96514b8fd1d60deccfc77abe77063258 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java @@ -34,6 +34,7 @@ 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.FlexiTableDataModelFactory; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableSearchEvent; 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.components.link.LinkFactory; @@ -88,7 +89,7 @@ public class CurriculumListManagerController extends FormBasicController impleme this.secCallback = secCallback; initForm(ureq); - loadModel(true); + loadModel(null, true); } @Override @@ -111,15 +112,17 @@ public class CurriculumListManagerController extends FormBasicController impleme toolsCol.setAlwaysVisible(true); columnsModel.addFlexiColumnModel(toolsCol); - tableModel = new CurriculumManagerDataModel(columnsModel); + tableModel = new CurriculumManagerDataModel(columnsModel, getLocale()); tableEl = uifactory.addTableElement(getWindowControl(), "table", tableModel, 20, false, getTranslator(), formLayout); tableEl.setCustomizeColumns(true); tableEl.setEmtpyTableMessageKey("table.curriculum.empty"); tableEl.setAndLoadPersistedPreferences(ureq, "cur-curriculum-manage"); + tableEl.setSearchEnabled(true); } - private void loadModel(boolean reset) { + private void loadModel(String searchString, boolean reset) { CurriculumSearchParameters params = new CurriculumSearchParameters(); + params.setSearchString(searchString); List<Curriculum> curriculums = curriculumService.getCurriculums(params); List<CurriculumRow> rows = curriculums.stream() .map(this::forgeRow).collect(Collectors.toList()); @@ -149,13 +152,13 @@ public class CurriculumListManagerController extends FormBasicController impleme protected void event(UserRequest ureq, Controller source, Event event) { if(newCurriculumCtrl == source) { if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) { - loadModel(true); + loadModel(tableEl.getQuickSearchString(), true); } cmc.deactivate(); cleanUp(); } else if(editCurriculumCtrl == source) { if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) { - loadModel(false); + loadModel(tableEl.getQuickSearchString(), false); } cmc.deactivate(); cleanUp(); @@ -192,6 +195,8 @@ public class CurriculumListManagerController extends FormBasicController impleme CurriculumRow row = tableModel.getObject(se.getIndex()); doSelectCurriculum(ureq, row); } + } else if(event instanceof FlexiTableSearchEvent) { + doSearch((FlexiTableSearchEvent)event); } } else if (source instanceof FormLink) { FormLink link = (FormLink)source; @@ -203,6 +208,10 @@ public class CurriculumListManagerController extends FormBasicController impleme super.formInnerEvent(ureq, source, event); } + private void doSearch(FlexiTableSearchEvent event) { + loadModel(event.getSearch(), true); + } + private void doNewCurriculum(UserRequest ureq) { if(newCurriculumCtrl != null) return; diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java index 19596b80c10e2b33cfe0df4d239773da4b31d433..c00e3a680f808f484f465cd3d79c9ed0cd845354 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java @@ -19,6 +19,9 @@ */ package org.olat.modules.curriculum.ui; +import java.util.List; +import java.util.Locale; + import org.olat.core.commons.persistence.SortKey; import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiSortableColumnDef; @@ -34,13 +37,19 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFl public class CurriculumManagerDataModel extends DefaultFlexiTableDataModel<CurriculumRow> implements SortableFlexiTableDataModel<CurriculumRow> { - public CurriculumManagerDataModel(FlexiTableColumnModel columnsModel) { + private final Locale locale; + + public CurriculumManagerDataModel(FlexiTableColumnModel columnsModel, Locale locale) { super(columnsModel); + this.locale = locale; } @Override - public void sort(SortKey sortKey) { - // + public void sort(SortKey orderBy) { + if(orderBy != null) { + List<CurriculumRow> rows = new CurriculumManagerTableSort(orderBy, this, locale).sort(); + super.setObjects(rows); + } } @Override @@ -62,7 +71,7 @@ implements SortableFlexiTableDataModel<CurriculumRow> { @Override public CurriculumManagerDataModel createCopyWithEmptyList() { - return new CurriculumManagerDataModel(getTableColumnModel()); + return new CurriculumManagerDataModel(getTableColumnModel(), locale); } public enum CurriculumCols implements FlexiSortableColumnDef { diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerTableSort.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerTableSort.java new file mode 100644 index 0000000000000000000000000000000000000000..9b5787ef89543eb85b6b393cc01264093889cda0 --- /dev/null +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerTableSort.java @@ -0,0 +1,39 @@ +/** + * <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> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.curriculum.ui; + +import java.util.Locale; + +import org.olat.core.commons.persistence.SortKey; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate; + +/** + * + * Initial date: 4 juin 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class CurriculumManagerTableSort extends SortableFlexiTableModelDelegate<CurriculumRow> { + + public CurriculumManagerTableSort(SortKey orderBy, CurriculumManagerDataModel model, Locale locale) { + super(orderBy, model, locale); + } + +} diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties index 9bb522b152dfe958ae96e5c8bbb9ad9b2de77a28..f46efc3fea41e76fc2565a98318704022e7567e2 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties @@ -10,6 +10,8 @@ admin.description=Curriculum Konfiguration admin.menu.title=Curriculum admin.menu.title.alt=Curriculum admin.title=$\:admin.menu.title +role.coach=Betreuer +role.curriculummanager=Curriculumverwalter confirm.delete.element.type.sucessfull=Der Typ "{0}" wurde erfolgreich gel\u00F6scht. confirmation.delete.type=Wollen Sie wirklich den Typ "{0}" l\u00F6schen? confirmation.delete.type.title=Typ "{0}" l\u00F6schen @@ -34,6 +36,8 @@ details.copy=Kopieren details.delete=L\u00F6schen info.copy.element.type.sucessfull=Der Typ "{0}" wurde erfolgreich kopiert. move.element=Element schieben +role.owner=Kursbesitzer +role.participant=Teilnehmer remove.memberships=Entfernen resources.add=$add.resources resources.add.title= diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties index d2d1d8fd4e79835de2a9eee3481ed8ac7646ca6c..1a204932b748788a4b7caed76ad13983e7ecb8d5 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties @@ -10,6 +10,8 @@ admin.description=Curriculum configuration admin.menu.title=Curriculum admin.menu.title.alt=Curriculum admin.title=$\:admin.menu.title +role.coach=Coach +role.curriculummanager=Curriculum manager confirm.delete.element.type.sucessfull=The type "{0}" was successfully deleted. confirmation.delete.type=Do you really want to delete this type "{0}"? confirmation.delete.type.title=Delete type "{0}" @@ -34,6 +36,8 @@ details.copy=Copy details.delete=Delete info.copy.element.type.sucessfull=The type "{0}" was successfully copied. move.element=Move element +role.owner=Course owner +role.participant=Participant remove.memberships=Remove resources.add=$add.resources supervisor=Fachvorsteher (supervisor) diff --git a/src/main/java/org/olat/repository/RepositoryManager.java b/src/main/java/org/olat/repository/RepositoryManager.java index d0ef89acf617ff63dd9db1a84470fbd114a2cb1e..41a26aa00f9b242b434e359aba37f292a265dcff 100644 --- a/src/main/java/org/olat/repository/RepositoryManager.java +++ b/src/main/java/org/olat/repository/RepositoryManager.java @@ -1974,21 +1974,6 @@ public class RepositoryManager { return new ArrayList<>(memberships.values()); } - public List<RepositoryEntryMembership> getOwnersMembership2(List<RepositoryEntry> res) { - if(res== null || res.isEmpty()) return Collections.emptyList(); - - StringBuilder sb = new StringBuilder(400); - sb.append("select distinct membership from ").append(RepositoryEntryMembership.class.getName()).append(" membership ") - .append(" where membership.repoKey in (:repoKey)"); - - List<Long> repoKeys = PersistenceHelper.toKeys(res); - TypedQuery<RepositoryEntryMembership> query = dbInstance.getCurrentEntityManager() - .createQuery(sb.toString(), RepositoryEntryMembership.class) - .setParameter("repoKey", repoKeys); - - return query.getResultList(); - } - public void updateRepositoryEntryMemberships(Identity ureqIdentity, Roles ureqRoles, RepositoryEntry re, List<RepositoryEntryPermissionChangeEvent> changes, MailPackage mailing) { diff --git a/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java b/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java index 4edcdb658076114804c08e19bd32cab926b3ceef..d49ff8f2865db9bb82c0d14bccfebcd2ae72e633 100644 --- a/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java +++ b/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java @@ -637,6 +637,22 @@ public class RepositoryEntryRelationDAO { .getResultList(); } + public boolean hasRelation(Group group, RepositoryEntryRef re) { + if(re == null || group == null) return false; + + String query = "select rel.key from repoentrytogroup as rel where rel.entry.key=:repoKey and rel.group.key=:groupKey"; + + List<Long> relations = dbInstance.getCurrentEntityManager() + .createQuery(query, Long.class) + .setParameter("repoKey", re.getKey()) + .setParameter("groupKey", group.getKey()) + .setFirstResult(0) + .setMaxResults(1) + .getResultList(); + return relations != null && !relations.isEmpty() && relations.get(0) != null; + } + + /** * Get the relation from a base group to the repository entries * diff --git a/src/main/java/org/olat/repository/model/RepositoryEntryMembership.java b/src/main/java/org/olat/repository/model/RepositoryEntryMembership.java index d56ab13ecedfe5125a349ba72705a29c75bb8cad..4df56e42fe658f9bca7977980e68e09a986fbacc 100644 --- a/src/main/java/org/olat/repository/model/RepositoryEntryMembership.java +++ b/src/main/java/org/olat/repository/model/RepositoryEntryMembership.java @@ -1,4 +1,5 @@ /** + * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> diff --git a/src/main/java/org/olat/repository/ui/author/RepositoryMembersController.java b/src/main/java/org/olat/repository/ui/author/RepositoryMembersController.java index 3a1d9b7b2bccb10dc43483c819da2715f7ff0a2e..fe0189aec8ca465208f1cd7eded58fb78a92d1ca 100644 --- a/src/main/java/org/olat/repository/ui/author/RepositoryMembersController.java +++ b/src/main/java/org/olat/repository/ui/author/RepositoryMembersController.java @@ -21,6 +21,7 @@ package org.olat.repository.ui.author; import java.util.List; +import org.olat.basesecurity.GroupRoles; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -47,7 +48,7 @@ import org.olat.group.BusinessGroupService; import org.olat.group.model.BusinessGroupMembershipChange; import org.olat.group.ui.main.AbstractMemberListController; import org.olat.group.ui.main.MemberPermissionChangeEvent; -import org.olat.group.ui.main.MemberView; +import org.olat.group.ui.main.MemberRow; import org.olat.group.ui.main.SearchMembersParams; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryManagedFlag; @@ -77,7 +78,7 @@ public class RepositoryMembersController extends AbstractMemberListController { Util.createPackageTranslator(RepositoryService.class, ureq.getLocale(), Util.createPackageTranslator(AbstractMemberListController.class, ureq.getLocale()))); - params = new SearchMembersParams(true, true, true, true, true, true, true); + params = new SearchMembersParams(true, GroupRoles.owner, GroupRoles.coach, GroupRoles.participant, GroupRoles.waiting); reloadModel(); } @@ -128,7 +129,7 @@ public class RepositoryMembersController extends AbstractMemberListController { } @Override - protected void doOpenAssessmentTool(UserRequest ureq, MemberView member) { + protected void doOpenAssessmentTool(UserRequest ureq, MemberRow member) { // } diff --git a/src/main/java/org/olat/user/restapi/OrganisationsWebService.java b/src/main/java/org/olat/user/restapi/OrganisationsWebService.java index b14a12fd5d9db09a4be0097155048853d127445a..d2a71d8a720ff8f4d52f57fcc19f050135dbc37d 100644 --- a/src/main/java/org/olat/user/restapi/OrganisationsWebService.java +++ b/src/main/java/org/olat/user/restapi/OrganisationsWebService.java @@ -21,10 +21,12 @@ package org.olat.user.restapi; import static org.olat.restapi.security.RestSecurityHelper.isAdmin; +import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -36,13 +38,16 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.OrganisationManagedFlag; +import org.olat.basesecurity.OrganisationRoles; import org.olat.basesecurity.OrganisationService; import org.olat.basesecurity.OrganisationType; import org.olat.basesecurity.model.OrganisationRefImpl; import org.olat.basesecurity.model.OrganisationTypeRefImpl; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; import org.olat.core.id.Organisation; /** @@ -201,7 +206,8 @@ public class OrganisationsWebService { @Path("{organisationKey}") @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) - public Response postOrganisation(@PathParam("organisationKey") Long organisationKey, OrganisationVO organisation, @Context HttpServletRequest httpRequest) { + public Response postOrganisation(@PathParam("organisationKey") Long organisationKey, OrganisationVO organisation, + @Context HttpServletRequest httpRequest) { boolean isSystemAdministrator = isAdmin(httpRequest); if(!isSystemAdministrator) { return Response.serverError().status(Status.UNAUTHORIZED).build(); @@ -264,6 +270,200 @@ public class OrganisationsWebService { return new OrganisationTypesWebService(); } + /** + * Get all members of the specified organisation with the specified role. + * + * @response.representation.200.qname {http://www.example.com}userVO + * @response.representation.200.mediaType application/xml, application/json + * @response.representation.200.doc The array of members + * @response.representation.200.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes} + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The organisation was not found + * @response.representation.409.doc The rolle is not valid + * @param httpRequest The HTTP request + * @return It returns an array of <code>UserVO</code> + */ + @GET + @Path("{organisationKey}/{role}") + public Response getMembers(@PathParam("organisationKey") Long organisationKey, @PathParam("role") String role, + @Context HttpServletRequest httpRequest) { + boolean isSystemAdministrator = isAdmin(httpRequest); + if(!isSystemAdministrator) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + return getMembers(organisationKey, getRoles(role)); + } + + private Response getMembers(Long organisationKey, OrganisationRoles role) { + OrganisationService organisationService = CoreSpringFactory.getImpl(OrganisationService.class); + + Organisation organisation = organisationService.getOrganisation(new OrganisationRefImpl(organisationKey)); + if(organisation == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(role == null) { + return Response.serverError().status(Status.CONFLICT).build(); + } + + List<Identity> members = organisationService.getMembersIdentity(organisation, role); + List<UserVO> voList = new ArrayList<>(members.size()); + for(Identity member:members) { + voList.add(UserVOFactory.get(member)); + } + return Response.ok(voList.toArray(new UserVO[voList.size()])).build(); + } + + /** + * Make the specified user a member of the specified organization + * with the specified role. + * + * @response.representation.200.doc The membership was added + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The organization or the identity was not found + * @param organisationKey The organization primary key + * @param role The role + * @param identityKey The member to make a coach of + * @param httpRequest The HTTP request + * @return Nothing + */ + @PUT + @Path("{organisationKey}/{role}/{identityKey}") + public Response putMember(@PathParam("organisationKey") Long organisationKey, @PathParam("role") String role, + @PathParam("identityKey") Long identityKey, @Context HttpServletRequest httpRequest) { + boolean isSystemAdministrator = isAdmin(httpRequest); + if(!isSystemAdministrator) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + return putMember(organisationKey, identityKey, getRoles(role)); + } + + private Response putMember(Long organisationKey, Long identityKey, OrganisationRoles role) { + OrganisationService organisationService = CoreSpringFactory.getImpl(OrganisationService.class); + Organisation organisation = organisationService.getOrganisation(new OrganisationRefImpl(organisationKey)); + if(organisation == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(role == null) { + return Response.serverError().status(Status.CONFLICT).build(); + } + + BaseSecurity securityManager = CoreSpringFactory.getImpl(BaseSecurity.class); + Identity identity = securityManager.loadIdentityByKey(identityKey); + if(identity == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + organisationService.addMember(organisation, identity, role); + return Response.ok().build(); + } + + /** + * Add a membership to the specified curriculum element. + * + * @response.representation.qname {http://www.example.com}curriculumElementMemberVO + * @response.representation.mediaType application/xml, application/json + * @response.representation.doc The curriculum element membership to persist + * @response.representation.example {@link org.olat.modules.curriculum.restapi.Examples#SAMPLE_CURRICULUMELEMENTMEMBERVO} + * @response.representation.200.doc The membership was persisted + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The curriculum element or the identity was not found + * @response.representation.409.doc The role is not allowed + * @param organisationKey The curriculum element primary key + * @param role The membership informations + * @return Nothing + */ + @PUT + @Path("{organisationKey}/{role}") + public Response putMembers(@PathParam("organisationKey") Long organisationKey, @PathParam("role") String role, + UserVO[] members, @Context HttpServletRequest httpRequest) { + boolean isSystemAdministrator = isAdmin(httpRequest); + if(!isSystemAdministrator) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + + OrganisationService organisationService = CoreSpringFactory.getImpl(OrganisationService.class); + Organisation organisation = organisationService.getOrganisation(new OrganisationRefImpl(organisationKey)); + if(organisation == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + if(getRoles(role) == null) { + return Response.serverError().status(Status.CONFLICT).build(); + } + + BaseSecurity securityManager = CoreSpringFactory.getImpl(BaseSecurity.class); + for(UserVO member:members) { + Identity identity = securityManager.loadIdentityByKey(member.getKey()); + if(identity != null) { + organisationService.addMember(organisation, identity, getRoles(role)); + } + } + return Response.ok().build(); + } + + /** + * Remove the membership of the identity from the specified organization and role. + * + * @response.representation.200.doc The membership was removed + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The organization or the identity was not found + * @param curriculumElementKey The curriculum element primary key + * @param identityKey The member to remove + * @return Nothing + */ + @DELETE + @Path("{organisationKey}/{role}/{identityKey}") + public Response deleteMember(@PathParam("organisationKey") Long organisationKey, @PathParam("role") String role, + @PathParam("identityKey") Long identityKey, @Context HttpServletRequest httpRequest) { + boolean isSystemAdministrator = isAdmin(httpRequest); + if(!isSystemAdministrator) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + return deleteMember(organisationKey, identityKey, getRoles(role)); + } + + private Response deleteMember(Long organisationKey, Long identityKey, OrganisationRoles role) { + OrganisationService organisationService = CoreSpringFactory.getImpl(OrganisationService.class); + Organisation organisation = organisationService.getOrganisation(new OrganisationRefImpl(organisationKey)); + if(organisation == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + if(role == null) { + return Response.serverError().status(Status.CONFLICT).build(); + } + + BaseSecurity securityManager = CoreSpringFactory.getImpl(BaseSecurity.class); + Identity identity = securityManager.loadIdentityByKey(identityKey); + if(identity == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + organisationService.removeMember(organisation, identity, role); + return Response.ok().build(); + } + + /** + * Convert beautified role to enum. + * + * @param role + * @return The role enum or null + */ + private OrganisationRoles getRoles(String role) { + if(OrganisationRoles.isValue(role)) { + return OrganisationRoles.valueOf(role); + } else if("coaches".equals(role)) { + return OrganisationRoles.coach; + } + + if(role.endsWith("s")) { + role = role.substring(0, role.length() - 1); + } + if(OrganisationRoles.isValue(role)) { + return OrganisationRoles.valueOf(role); + } + return null; + } + private OrganisationVO[] toArrayOfVOes(List<Organisation> organisations) { int i=0; diff --git a/src/main/java/org/olat/user/restapi/UserVO.java b/src/main/java/org/olat/user/restapi/UserVO.java index b30341c23f8543ad9c76834ce15273491c8d1676..22dfcbb44d53804968ed405b2bba19e73ed4a73d 100644 --- a/src/main/java/org/olat/user/restapi/UserVO.java +++ b/src/main/java/org/olat/user/restapi/UserVO.java @@ -30,8 +30,6 @@ import javax.xml.bind.annotation.XmlRootElement; /** * - * Description:<br> - * TODO: srosse Class Description for UserVO * * <P> * Initial Date: 7 apr. 2010 <br> @@ -52,7 +50,7 @@ public class UserVO { @XmlElementWrapper(name="properties") @XmlElement(name="property") - private List<UserPropertyVO> properties = new ArrayList<UserPropertyVO>(); + private List<UserPropertyVO> properties = new ArrayList<>(); public UserVO() { //make JAXB happy diff --git a/src/main/java/org/olat/user/ui/organisation/RoleListController.java b/src/main/java/org/olat/user/ui/organisation/RoleListController.java index a8005a306c1dbf201d8ef2ff69c63aabac75161b..cd9e73ed3243946deb2a388628b8227b1d735807 100644 --- a/src/main/java/org/olat/user/ui/organisation/RoleListController.java +++ b/src/main/java/org/olat/user/ui/organisation/RoleListController.java @@ -56,7 +56,7 @@ public class RoleListController extends BasicController { } private Link addLink(OrganisationRoles role, List<String> links) { - Link link = LinkFactory.createLink(role.name(), role.name(), getTranslator(), mainVC, this, Link.LINK); + Link link = LinkFactory.createLink("role." + role.name(), role.name(), getTranslator(), mainVC, this, Link.LINK); link.setUserObject(role); mainVC.put(role.name(), link); links.add(role.name()); diff --git a/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_de.properties index cae64a39b8cf6cfb9ba0a42474af607c74f9462f..8d39503c354efda7b7d42ecf2eb2d50e1c1b26f5 100644 --- a/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_de.properties @@ -6,20 +6,22 @@ add.root.type=Organisationtyp erstellen admin.description=Organisationen verwalten admin.menu.title=Organisationen admin.menu.title.alt=Organisationen -administrator=Administrator -author=Author -coach=Betreuer +role.administrator=Administrator +role.author=Author +role.coach=Betreuer +role.curriculummanager=Curriculumverwalter confirm.remove.text=Wollen Sie wirklich diese Benutzer ihre Mitgliedschaft entfernen? confirm.remove.title=Mitglieder entfernen create.organisation=Neue Organisation erstellen -curriculummanager=Curriculumverwalter +role.curriculummanager=Curriculumverwalter edit.type=Organisationtyp editieren -groupmanager=Gruppenverwalter -guest=Gast +role.groupmanager=Gruppenverwalter +role.guest=Gast +role.principal=Principal institution.to.org=Ressourceverwaltung mit Institutionname zu Organisationen migrieren institution.to.org.explain=Erkl\u00E4rung institution.to.org.label=Migration -learnresourcemanager=Lernressourcenverwalter +role.learnresourcemanager=Lernressourcenverwalter migrate=Migrieren move.organisation=Organisation schieben organisation.admin.enabled=Organisationen einschalten @@ -34,9 +36,9 @@ organisation.structure=Organisationenstruktur organisation.type=Organisationtyp organisation.types=Organisationentypen organisation.user.management=Benutzerverwaltung -poolmanager=Poolverwalter +role.poolmanager=Poolverwalter remove.memberships=Entfernen -sysadmin=Systemadministrator +role.sysadmin=Systemadministrator table.header.displayName=Name table.header.edit=Editieren table.header.identifier=Org. ID @@ -57,7 +59,7 @@ type.cssClass=CSS Class type.description=Beschreibung type.displayname=Name type.identifier=Bezeichnung -user=Benutzer -usermanager=Benutzerverwalter +role.user=Benutzer +role.usermanager=Benutzerverwalter warning.atleastone.member=Sie m\u00FCssen mindestens ein Benutzer w\u00E4hlen. warning.organisation.deleted=Die Organisation wurde seit kurzem gel\u00F6scht. diff --git a/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_en.properties index 6bbb8cf4a7fbf9ca4af2d0547fcc86ad4cc230ad..97b79faebc55682e2b0c9008996d469323b3fc22 100644 --- a/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_en.properties @@ -6,20 +6,22 @@ add.root.type=Create organisation type admin.description=Manage your organisations admin.menu.title=Organisations admin.menu.title.alt=Organisations -administrator=Administrator -author=Author -coach=Coach +role.administrator=Administrator +role.author=Author +role.coach=Coach +role.curriculummanager=Curriculum manager confirm.remove.text=Do you really want to remove the memberships of this user? confirm.remove.title=Remove membership create.organisation=Create new organisation -curriculummanager=Curriculum manager +role.curriculummanager=Curriculum manager edit.type=Edit organisation type -groupmanager=Group manager -guest=Guest +role.groupmanager=Group manager +role.guest=Guest +role.principal=Principal institution.to.org=Migrate learn resource management by institution name to organisation institution.to.org.explain=Explanation institution.to.org.label=Migration -learnresourcemanager=Learn resource manager +role.learnresourcemanager=Learn resource manager migrate=Migrate move.organisation=Move organisation organisation.admin.enabled=Enable organisations @@ -34,9 +36,9 @@ organisation.structure=Organisations structures organisation.type=Organisation type organisation.types=Organisations types organisation.user.management=User management -poolmanager=Question bank manager +role.poolmanager=Question bank manager remove.memberships=Remove -sysadmin=System administrator +role.sysadmin=System administrator table.header.displayName=Name table.header.edit=Edit table.header.identifier=Org. ID @@ -57,7 +59,7 @@ type.cssClass=CSS class type.description=Description type.displayname=Name type.identifier=Identifier -user=User -usermanager=User manager +role.user=User +role.usermanager=User manager warning.atleastone.member=You need to select at least one user. warning.organisation.deleted=The organisation was deleted. diff --git a/src/main/java/org/olat/user/ui/organisation/component/RoleFlexiCellRenderer.java b/src/main/java/org/olat/user/ui/organisation/component/RoleFlexiCellRenderer.java index e3077c88c8c9cc439f186bda4420748608d4eb3e..6bbc11551ebb8ef473403af7bd87a17d2c90f3d7 100644 --- a/src/main/java/org/olat/user/ui/organisation/component/RoleFlexiCellRenderer.java +++ b/src/main/java/org/olat/user/ui/organisation/component/RoleFlexiCellRenderer.java @@ -47,11 +47,11 @@ public class RoleFlexiCellRenderer implements FlexiCellRenderer { URLBuilder ubu, Translator trans) { if(cellValue instanceof OrganisationRoles) { OrganisationRoles role = (OrganisationRoles)cellValue; - target.append(translator.translate(role.name())); + target.append(translator.translate("role.".concat(role.name()))); } else if(cellValue instanceof String) { String val = (String)cellValue; if(OrganisationRoles.valid(val)) { - target.append(translator.translate(OrganisationRoles.valueOf(val).name())); + target.append(translator.translate("role.".concat(OrganisationRoles.valueOf(val).name()))); } else { target.append(StringHelper.escapeHtml(val)); } diff --git a/src/test/java/org/olat/modules/curriculum/manager/CurriculumDAOTest.java b/src/test/java/org/olat/modules/curriculum/manager/CurriculumDAOTest.java index 0ca7a0812b192dc0b009f91f22f4fee691d6b703..816ba1b79c8ae14a1e92d2e1f6316bba9f604ee4 100644 --- a/src/test/java/org/olat/modules/curriculum/manager/CurriculumDAOTest.java +++ b/src/test/java/org/olat/modules/curriculum/manager/CurriculumDAOTest.java @@ -21,6 +21,7 @@ package org.olat.modules.curriculum.manager; import java.util.Collections; import java.util.List; +import java.util.UUID; import org.junit.Assert; import org.junit.Test; @@ -111,4 +112,34 @@ public class CurriculumDAOTest extends OlatTestCase { Assert.assertEquals(organisation, curriculums.get(0).getOrganisation()); Assert.assertNotNull(((CurriculumImpl)curriculums.get(0)).getGroup().getKey()); } + + @Test + public void search_searchString() { + String identifier = UUID.randomUUID().toString(); + String displayName = UUID.randomUUID().toString(); + Curriculum curriculum = curriculumDao.createAndPersist(identifier, displayName, "Short desc.", null); + dbInstance.commitAndCloseSession(); + + // search something which doesn't exists + CurriculumSearchParameters params = new CurriculumSearchParameters(); + params.setSearchString("AAAAAAAA"); + List<Curriculum> curriculums = curriculumDao.search(params); + Assert.assertTrue(curriculums.isEmpty()); + + // search by identifier + params.setSearchString(identifier); + List<Curriculum> curriculumById = curriculumDao.search(params); + Assert.assertEquals(1, curriculumById.size()); + Assert.assertEquals(curriculum, curriculumById.get(0)); + + // search by identifier + params.setSearchString(displayName.substring(0, 25).toUpperCase()); + List<Curriculum> curriculumByName = curriculumDao.search(params); + Assert.assertTrue(curriculumByName.contains(curriculum)); + + // search by primary key + params.setSearchString(curriculum.getKey().toString()); + List<Curriculum> curriculumByKey = curriculumDao.search(params); + Assert.assertTrue(curriculumByKey.contains(curriculum)); + } } diff --git a/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java b/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java index 42300f605bf6b89a740d53a609062d0d33ca2e1b..673124fba10a9efca345d23410e17b53f7825743 100644 --- a/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java +++ b/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java @@ -225,7 +225,7 @@ public class CurriculumElementDAOTest extends OlatTestCase { Identity supervisor = JunitTestHelper.createAndPersistIdentityAsRndUser("cur-supervisor-1"); Curriculum curriculum = curriculumService.createCurriculum("cur-for-el-4", "Curriculum for element", "Curriculum", null); CurriculumElement element = curriculumService.createCurriculumElement("Element-4", "4. Element", null, null, null, null, curriculum); - curriculumService.addMember(element, supervisor, CurriculumRoles.supervisor); + curriculumService.addMember(element, supervisor, CurriculumRoles.curriculummanager); dbInstance.commitAndCloseSession(); List<CurriculumElementMember> members = curriculumElementDao.getMembers(element); @@ -233,6 +233,20 @@ public class CurriculumElementDAOTest extends OlatTestCase { Assert.assertEquals(1, members.size()); CurriculumElementMember member = members.get(0); Assert.assertEquals(supervisor, member.getIdentity()); - Assert.assertEquals(CurriculumRoles.supervisor.name(), member.getRole()); + Assert.assertEquals(CurriculumRoles.curriculummanager.name(), member.getRole()); + } + + @Test + public void getMembersIdentity() { + Identity supervisor = JunitTestHelper.createAndPersistIdentityAsRndUser("cur-supervisor-1"); + Curriculum curriculum = curriculumService.createCurriculum("cur-for-el-4", "Curriculum for element", "Curriculum", null); + CurriculumElement element = curriculumService.createCurriculumElement("Element-4", "4. Element", null, null, null, null, curriculum); + curriculumService.addMember(element, supervisor, CurriculumRoles.curriculummanager); + dbInstance.commitAndCloseSession(); + + List<Identity> members = curriculumElementDao.getMembersIdentity(element, CurriculumRoles.curriculummanager.name()); + Assert.assertNotNull(members); + Assert.assertEquals(1, members.size()); + Assert.assertEquals(supervisor, members.get(0)); } } diff --git a/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java b/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java index 2bbd97a47b5653eef9c26a8576bb63b207cbac16..e1355c80ddcbf1247a707d4734f2156338abe9db 100644 --- a/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java +++ b/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java @@ -84,7 +84,6 @@ public class CurriculumRepositoryEntryRelationDAOTest extends OlatTestCase { Assert.assertEquals(entry, entries.get(0)); } - @Test public void getCurriculumElements() { Curriculum curriculum = curriculumService.createCurriculum("cur-el-rel-2", "Curriculum for relation", "Curriculum", null); @@ -101,5 +100,43 @@ public class CurriculumRepositoryEntryRelationDAOTest extends OlatTestCase { Assert.assertEquals(element, elements.get(0)); } - + @Test + public void getRelations() { + Curriculum curriculum = curriculumService.createCurriculum("cur-el-rel-3", "Curriculum for relation", "Curriculum", null); + CurriculumElement element = curriculumService.createCurriculumElement("Element-for-rel", "Element for relation", null, null, null, null, curriculum); + Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("cur-el-re-auth"); + RepositoryEntry entry = JunitTestHelper.createRandomRepositoryEntry(author); + dbInstance.commit(); + curriculumService.addRepositoryEntry(element, entry, false); + dbInstance.commitAndCloseSession(); + + List<CurriculumRepositoryEntryRelation> relations = curriculumRepositoryEntryRelationDao.getRelations(entry, element); + Assert.assertNotNull(relations); + Assert.assertEquals(1, relations.size()); + Assert.assertEquals(element, relations.get(0).getCurriculumElement()); + Assert.assertEquals(entry, relations.get(0).getEntry()); + } + + @Test + public void deleteRelations() { + Curriculum curriculum = curriculumService.createCurriculum("cur-el-rel-4", "Curriculum for relation", "Curriculum", null); + CurriculumElement element = curriculumService.createCurriculumElement("Element-for-rel", "Element for relation", null, null, null, null, curriculum); + Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("cur-el-re-auth"); + RepositoryEntry entry = JunitTestHelper.createRandomRepositoryEntry(author); + dbInstance.commit(); + curriculumService.addRepositoryEntry(element, entry, false); + dbInstance.commitAndCloseSession(); + + // check if the relation is really there. + List<CurriculumRepositoryEntryRelation> relations = curriculumRepositoryEntryRelationDao.getRelations(entry, element); + Assert.assertEquals(1, relations.size()); + + // delete the relations + curriculumRepositoryEntryRelationDao.deleteRelation(entry, element); + dbInstance.commitAndCloseSession(); + + // check that there isn't a relation left + List<CurriculumRepositoryEntryRelation> deletedRelations = curriculumRepositoryEntryRelationDao.getRelations(entry, element); + Assert.assertTrue(deletedRelations.isEmpty()); + } } diff --git a/src/test/java/org/olat/repository/manager/RepositoryEntryRelationDAOTest.java b/src/test/java/org/olat/repository/manager/RepositoryEntryRelationDAOTest.java index f72ddc06f9025fc4818e69edbfdf385eb506aae8..9076f8868446350e978f55e7736d2b77fdb5c0d5 100644 --- a/src/test/java/org/olat/repository/manager/RepositoryEntryRelationDAOTest.java +++ b/src/test/java/org/olat/repository/manager/RepositoryEntryRelationDAOTest.java @@ -425,8 +425,8 @@ public class RepositoryEntryRelationDAOTest extends OlatTestCase { } @Test - public void getRelations() { - Identity id = JunitTestHelper.createAndPersistIdentityAsUser("re-member-lc-" + UUID.randomUUID().toString()); + public void getRelations_group() { + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("re-member-lc-" ); RepositoryEntry re1 = JunitTestHelper.createAndPersistRepositoryEntry(); RepositoryEntry re2 = JunitTestHelper.createAndPersistRepositoryEntry(); @@ -444,6 +444,40 @@ public class RepositoryEntryRelationDAOTest extends OlatTestCase { Assert.assertTrue(relations.get(1).getEntry().equals(re1) || relations.get(1).getEntry().equals(re2)); } + @Test + public void getRelations_repositoryEntry() { + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("re-member-lc-"); + RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry(); + + BusinessGroup group = businessGroupService.createBusinessGroup(null, "get relations", "tg", null, null, false, false, re); + businessGroupRelationDao.addRole(id, group, GroupRoles.coach.name()); + dbInstance.commitAndCloseSession(); + + //get the relations from the business group's base group to the repository entry + List<RepositoryEntryToGroupRelation> relations = repositoryEntryRelationDao.getRelations(re); + Assert.assertNotNull(relations); + Assert.assertEquals(3, relations.size()); + Assert.assertTrue(relations.get(0).getEntry().equals(re)); + } + + @Test + public void hasRelation() { + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("re-member-lc-"); + RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry(); + RepositoryEntry reMarker = JunitTestHelper.createAndPersistRepositoryEntry(); + + BusinessGroup group = businessGroupService.createBusinessGroup(null, "get relations", "tg", null, null, false, false, re); + businessGroupRelationDao.addRole(id, group, GroupRoles.coach.name()); + dbInstance.commitAndCloseSession(); + + // The repository entry has a relation with the business group + boolean hasRelation = repositoryEntryRelationDao.hasRelation(group.getBaseGroup(), re); + Assert.assertTrue(hasRelation); + // The marker repository entry doesn't have a relation with the business group + boolean hasNotRelation = repositoryEntryRelationDao.hasRelation(group.getBaseGroup(), reMarker); + Assert.assertFalse(hasNotRelation); + } + @Test public void getIdentitiesWithRole() { Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("id-role-1-"); diff --git a/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java b/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java index ada2e6ef5a0286282b13a91185f23898e1eb5494..466ea2acdfc2f939a810ec8af3ecacac6aa6bb9c 100644 --- a/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java +++ b/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java @@ -30,7 +30,9 @@ import java.util.List; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriBuilder; +import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; @@ -42,15 +44,23 @@ import org.junit.Assert; import org.junit.Test; import org.olat.basesecurity.OrganisationService; import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; import org.olat.core.id.Organisation; import org.olat.modules.curriculum.Curriculum; import org.olat.modules.curriculum.CurriculumElement; import org.olat.modules.curriculum.CurriculumElementManagedFlag; import org.olat.modules.curriculum.CurriculumElementType; +import org.olat.modules.curriculum.CurriculumRoles; import org.olat.modules.curriculum.CurriculumService; +import org.olat.modules.curriculum.model.CurriculumElementMember; import org.olat.modules.curriculum.model.CurriculumElementRefImpl; +import org.olat.modules.curriculum.restapi.CurriculumElementMemberVO; import org.olat.modules.curriculum.restapi.CurriculumElementVO; +import org.olat.repository.RepositoryEntry; +import org.olat.test.JunitTestHelper; import org.olat.test.OlatJerseyTestCase; +import org.olat.user.restapi.UserVO; +import org.olat.user.restapi.UserVOFactory; import org.springframework.beans.factory.annotation.Autowired; /** @@ -84,8 +94,7 @@ public class CurriculumElementsWebServiceTest extends OlatJerseyTestCase { HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true); HttpResponse response = conn.execute(method); Assert.assertEquals(200, response.getStatusLine().getStatusCode()); - InputStream body = response.getEntity().getContent(); - List<CurriculumElementVO> elementVoes = parseCurriculumElementArray(body); + List<CurriculumElementVO> elementVoes = parseCurriculumElementArray(response.getEntity()); Assert.assertNotNull(elementVoes); Assert.assertEquals(2, elementVoes.size()); @@ -345,14 +354,505 @@ public class CurriculumElementsWebServiceTest extends OlatJerseyTestCase { } - protected List<CurriculumElementVO> parseCurriculumElementArray(InputStream body) { - try { + @Test + public void addRepositoryEntryToCurriculumElement() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 4", "REST-p-4-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-11", "Element 11", null, null, null, null, curriculum); + dbInstance.commitAndCloseSession(); + + Identity author = JunitTestHelper.createAndPersistIdentityAsRndAuthor("rest-auth-1"); + RepositoryEntry course = JunitTestHelper.createRandomRepositoryEntry(author); + dbInstance.commitAndCloseSession(); + + // add the relation + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("entries").path(course.getKey().toString()).build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<RepositoryEntry> entries = curriculumService.getRepositoryEntries(element); + Assert.assertNotNull(entries); + Assert.assertEquals(1, entries.size()); + Assert.assertEquals(course, entries.get(0)); + } + + @Test + public void removeRepositoryEntryFromCurriculumElement() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 5", "REST-p-5-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-12", "Element 12", null, null, null, null, curriculum); + dbInstance.commit(); + + Identity author = JunitTestHelper.createAndPersistIdentityAsRndAuthor("rest-auth-2"); + RepositoryEntry entry = JunitTestHelper.createRandomRepositoryEntry(author); + dbInstance.commit(); + + curriculumService.addRepositoryEntry(element, entry, false); + dbInstance.commitAndCloseSession(); + + List<RepositoryEntry> entries = curriculumService.getRepositoryEntries(element); + Assert.assertEquals(1, entries.size()); + + + //try to delete the relation + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("entries").path(entry.getKey().toString()).build(); + HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<RepositoryEntry> deletedRelations = curriculumService.getRepositoryEntries(element); + Assert.assertNotNull(deletedRelations); + Assert.assertTrue(deletedRelations.isEmpty()); + } + + @Test + public void getMemberships() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-1"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 5", "REST-p-5-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-12", "Element 12", null, null, null, null, curriculum); + dbInstance.commit(); + + curriculumService.addMember(element, member, CurriculumRoles.participant); + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("members").build(); + HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + List<CurriculumElementMemberVO> memberVoes = parseCurriculumElementMemberArray(response.getEntity()); + + Assert.assertNotNull(memberVoes); + Assert.assertEquals(1, memberVoes.size()); + Assert.assertEquals(member.getKey(), memberVoes.get(0).getIdentityKey()); + Assert.assertEquals("participant", memberVoes.get(0).getRole()); + } + + @Test + public void getUsers() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-6"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 8", "REST-p-8-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-14", "Element 14", null, null, null, null, curriculum); + dbInstance.commit(); + + curriculumService.addMember(element, member, CurriculumRoles.participant); + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("users").queryParam("role", "participant").build(); + HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + List<UserVO> memberVoes = parseUserArray(response.getEntity()); + + Assert.assertNotNull(memberVoes); + Assert.assertEquals(1, memberVoes.size()); + Assert.assertEquals(member.getKey(), memberVoes.get(0).getKey()); + } + + @Test + public void getUsers_curriculumManagers() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-6"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 8", "REST-p-8-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-14", "Element 14", null, null, null, null, curriculum); + dbInstance.commit(); + + curriculumService.addMember(element, member, CurriculumRoles.curriculummanager); + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("users").queryParam("role", "curriculummanager").build(); + HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + List<UserVO> memberVoes = parseUserArray(response.getEntity()); + + Assert.assertNotNull(memberVoes); + Assert.assertEquals(1, memberVoes.size()); + Assert.assertEquals(member.getKey(), memberVoes.get(0).getKey()); + } + + @Test + public void getParticipants() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-7"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 9", "REST-p-9-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-15", "Element 15", null, null, null, null, curriculum); + dbInstance.commit(); + + curriculumService.addMember(element, member, CurriculumRoles.participant); + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("participants").build(); + HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + List<UserVO> memberVoes = parseUserArray(response.getEntity()); + + Assert.assertNotNull(memberVoes); + Assert.assertEquals(1, memberVoes.size()); + Assert.assertEquals(member.getKey(), memberVoes.get(0).getKey()); + } + + @Test + public void getCoaches() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-10"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 10", "REST-p-10-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-16", "Element 16", null, null, null, null, curriculum); + dbInstance.commit(); + + curriculumService.addMember(element, member, CurriculumRoles.coach); + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("coaches").build(); + HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + List<UserVO> memberVoes = parseUserArray(response.getEntity()); + + Assert.assertNotNull(memberVoes); + Assert.assertEquals(1, memberVoes.size()); + Assert.assertEquals(member.getKey(), memberVoes.get(0).getKey()); + } + + @Test + public void getCurriculumManagers() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-10"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 10", "REST-p-10-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-16", "Element 16", null, null, null, null, curriculum); + dbInstance.commit(); + + curriculumService.addMember(element, member, CurriculumRoles.curriculummanager); + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("curriculummanagers").build(); + HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + List<UserVO> memberVoes = parseUserArray(response.getEntity()); + + Assert.assertNotNull(memberVoes); + Assert.assertEquals(1, memberVoes.size()); + Assert.assertEquals(member.getKey(), memberVoes.get(0).getKey()); + } + + @Test + public void addMembership() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-1"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 5", "REST-p-5-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-12", "Element 12", null, null, null, null, curriculum); + dbInstance.commit(); + + CurriculumElementMemberVO membershipVo = new CurriculumElementMemberVO(); + membershipVo.setIdentityKey(member.getKey()); + membershipVo.setRole("participant"); + membershipVo.setInheritanceMode("none"); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("members").build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + conn.addJsonEntity(method, membershipVo); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<CurriculumElementMember> members = curriculumService.getMembers(element); + Assert.assertNotNull(members); + Assert.assertEquals(1, members.size()); + Assert.assertEquals(member, members.get(0).getIdentity()); + Assert.assertEquals("participant", members.get(0).getRole()); + } + + @Test + public void addParticipant() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-11"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 11", "REST-p-11-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-17", "Element 17", null, null, null, null, curriculum); + dbInstance.commit(); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("participants").path(participant.getKey().toString()).build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<Identity> participants = curriculumService.getMembersIdentity(element, CurriculumRoles.participant); + Assert.assertNotNull(participants); + Assert.assertEquals(1, participants.size()); + Assert.assertEquals(participant, participants.get(0)); + } + + @Test + public void addCoach() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-12"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 12", "REST-p-12-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-18", "Element 18", null, null, null, null, curriculum); + dbInstance.commit(); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("coaches").path(coach.getKey().toString()).build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<Identity> coaches = curriculumService.getMembersIdentity(element, CurriculumRoles.coach); + Assert.assertNotNull(coaches); + Assert.assertEquals(1, coaches.size()); + Assert.assertEquals(coach, coaches.get(0)); + } + + @Test + public void addParticipants() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-13"); + Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-14"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 13", "REST-p-13-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-18", "Element 18", null, null, null, null, curriculum); + dbInstance.commit(); + + UserVO[] participants = new UserVO[] { + UserVOFactory.get(participant1), + UserVOFactory.get(participant2) + }; + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("participants").build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + conn.addJsonEntity(method, participants); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<Identity> participantList = curriculumService.getMembersIdentity(element, CurriculumRoles.participant); + Assert.assertNotNull(participantList); + Assert.assertEquals(2, participantList.size()); + } + + @Test + public void addCoaches() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity coach1 = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-15"); + Identity coach2 = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-16"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 16", "REST-p-16-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-20", "Element 20", null, null, null, null, curriculum); + dbInstance.commit(); + + UserVO[] coaches = new UserVO[] { + UserVOFactory.get(coach1), + UserVOFactory.get(coach2) + }; + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("coaches").build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + conn.addJsonEntity(method, coaches); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<Identity> coachList = curriculumService.getMembersIdentity(element, CurriculumRoles.coach); + Assert.assertNotNull(coachList); + Assert.assertEquals(2, coachList.size()); + } + + @Test + public void removeMembership() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-1"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 5", "REST-p-5-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-12", "Element 12", null, null, null, null, curriculum); + dbInstance.commit(); + + curriculumService.addMember(element, member, CurriculumRoles.participant); + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("members").path(member.getKey().toString()).build(); + HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<CurriculumElementMember> members = curriculumService.getMembers(element); + Assert.assertNotNull(members); + Assert.assertTrue(members.isEmpty()); + } + + @Test + public void removeParticipant() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-21"); + Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-22"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 21", "REST-p-21-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-21", "Element 21", null, null, null, null, curriculum); + dbInstance.commit(); + + curriculumService.addMember(element, participant, CurriculumRoles.participant); + curriculumService.addMember(element, coach, CurriculumRoles.coach); + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("participants").path(participant.getKey().toString()).build(); + HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<Identity> participants = curriculumService.getMembersIdentity(element, CurriculumRoles.participant); + Assert.assertTrue(participants.isEmpty()); + List<Identity> coaches = curriculumService.getMembersIdentity(element, CurriculumRoles.coach); + Assert.assertEquals(1, coaches.size()); + } + + @Test + public void removeCoach() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-23"); + Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-24"); + Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 24", "REST-p-24-organisation", "", null, null); + Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation); + CurriculumElement element = curriculumService.createCurriculumElement("Element-24", "Element 24", null, null, null, null, curriculum); + dbInstance.commit(); + + curriculumService.addMember(element, participant, CurriculumRoles.participant); + curriculumService.addMember(element, coach, CurriculumRoles.coach); + dbInstance.commitAndCloseSession(); + + URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString()) + .path("elements").path(element.getKey().toString()).path("coaches").path(coach.getKey().toString()).build(); + HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<Identity> coaches = curriculumService.getMembersIdentity(element, CurriculumRoles.coach); + Assert.assertTrue(coaches.isEmpty()); + List<Identity> participants = curriculumService.getMembersIdentity(element, CurriculumRoles.participant); + Assert.assertEquals(1, participants.size()); + } + + protected List<UserVO> parseUserArray(HttpEntity body) { + try(InputStream in = body.getContent()) { ObjectMapper mapper = new ObjectMapper(jsonFactory); - return mapper.readValue(body, new TypeReference<List<CurriculumElementVO>>(){/* */}); + return mapper.readValue(in, new TypeReference<List<UserVO>>(){/* */}); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + protected List<CurriculumElementVO> parseCurriculumElementArray(HttpEntity body) { + try(InputStream in = body.getContent()) { + ObjectMapper mapper = new ObjectMapper(jsonFactory); + return mapper.readValue(in, new TypeReference<List<CurriculumElementVO>>(){/* */}); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + protected List<CurriculumElementMemberVO> parseCurriculumElementMemberArray(HttpEntity body) { + try(InputStream in = body.getContent()) { + ObjectMapper mapper = new ObjectMapper(jsonFactory); + return mapper.readValue(in, new TypeReference<List<CurriculumElementMemberVO>>(){/* */}); } catch (Exception e) { e.printStackTrace(); return null; } } - } diff --git a/src/test/java/org/olat/restapi/OrganisationsWebServiceTest.java b/src/test/java/org/olat/restapi/OrganisationsWebServiceTest.java index 16de3bb799f79a16c3be813a100a45d576e8acb5..b147fe14ab83d215fb7bc4bb937272debdaafac5 100644 --- a/src/test/java/org/olat/restapi/OrganisationsWebServiceTest.java +++ b/src/test/java/org/olat/restapi/OrganisationsWebServiceTest.java @@ -30,23 +30,31 @@ import java.util.List; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriBuilder; +import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; +import org.apache.http.util.EntityUtils; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; import org.olat.basesecurity.OrganisationManagedFlag; +import org.olat.basesecurity.OrganisationRoles; import org.olat.basesecurity.OrganisationService; import org.olat.basesecurity.OrganisationType; import org.olat.basesecurity.model.OrganisationRefImpl; import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; import org.olat.core.id.Organisation; +import org.olat.test.JunitTestHelper; import org.olat.test.OlatJerseyTestCase; import org.olat.user.restapi.OrganisationVO; +import org.olat.user.restapi.UserVO; +import org.olat.user.restapi.UserVOFactory; import org.springframework.beans.factory.annotation.Autowired; /** @@ -304,7 +312,117 @@ public class OrganisationsWebServiceTest extends OlatJerseyTestCase { Assert.assertEquals(parentOrganisation, savedOrganisation.getRoot()); } + @Test + public void getMembers_users() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("org-member-11"); + Organisation organisation = organisationService.createOrganisation("REST Organisation 5", "REST-p-5-organisation", "", null, null); + organisationService.addMember(organisation, member, OrganisationRoles.user); + dbInstance.commit(); + + URI request = UriBuilder.fromUri(getContextURI()).path("organisations").path(organisation.getKey().toString()) + .path("users").build(); + HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + List<UserVO> users = parseUserArray(response.getEntity()); + Assert.assertNotNull(users); + Assert.assertEquals(1, users.size()); + Assert.assertEquals(member.getKey(), users.get(0).getKey()); + } + @Test + public void addMember_principal() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("org-member-12"); + Organisation organisation = organisationService.createOrganisation("REST Organisation 6", "REST-p-6-organisation", "", null, null); + dbInstance.commit(); + + URI request = UriBuilder.fromUri(getContextURI()).path("organisations").path(organisation.getKey().toString()) + .path("principals").path(member.getKey().toString()).build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<Identity> principals = organisationService.getMembersIdentity(organisation, OrganisationRoles.principal); + Assert.assertNotNull(principals); + Assert.assertEquals(1, principals.size()); + Assert.assertEquals(member, principals.get(0)); + } + + @Test + public void addMembers_author() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity author1 = JunitTestHelper.createAndPersistIdentityAsRndUser("org-member-14"); + Identity author2 = JunitTestHelper.createAndPersistIdentityAsRndUser("org-member-15"); + Organisation organisation = organisationService.createOrganisation("REST Organisation 7", "REST-p-7-organisation", "", null, null); + dbInstance.commit(); + + + UserVO[] authors = new UserVO[] { + UserVOFactory.get(author1), + UserVOFactory.get(author2) + }; + URI request = UriBuilder.fromUri(getContextURI()).path("organisations").path(organisation.getKey().toString()) + .path("authors").build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + conn.addJsonEntity(method, authors); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<Identity> authorList = organisationService.getMembersIdentity(organisation, OrganisationRoles.author); + Assert.assertNotNull(authorList); + Assert.assertEquals(2, authorList.size()); + } + + + @Test + public void removeMember_administrator() + throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); + assertTrue(conn.login("administrator", "openolat")); + + Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("org-member-13"); + Organisation organisation = organisationService.createOrganisation("REST Organisation 7", "REST-p-7-organisation", "", null, null); + organisationService.addMember(organisation, member, OrganisationRoles.administrator); + dbInstance.commit(); + + URI request = UriBuilder.fromUri(getContextURI()).path("organisations").path(organisation.getKey().toString()) + .path("administrators").path(member.getKey().toString()).build(); + HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON); + + HttpResponse response = conn.execute(method); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + List<Identity> administators = organisationService.getMembersIdentity(organisation, OrganisationRoles.administrator); + Assert.assertNotNull(administators); + Assert.assertTrue(administators.isEmpty()); + } + + protected List<UserVO> parseUserArray(HttpEntity entity) { + try(InputStream in=entity.getContent()) { + ObjectMapper mapper = new ObjectMapper(jsonFactory); + return mapper.readValue(in, new TypeReference<List<UserVO>>(){/* */}); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } protected List<OrganisationVO> parseOrganisationArray(InputStream body) { try {