Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
GroupsAndRightsController.java 12.13 KiB
/**
 * <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.course.groupsandrights;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement.Layout;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.components.form.flexible.impl.elements.MultipleSelectionElementImpl;
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.FlexiTableDataModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.components.table.DefaultTableDataModel;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
import org.olat.group.BusinessGroup;
import org.olat.group.BusinessGroupService;
import org.olat.group.right.BGRightManager;
import org.olat.group.right.BGRights;
import org.olat.group.right.BGRightsRole;
import org.olat.repository.RepositoryEntry;

/**
 * 
 * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
 */
public class GroupsAndRightsController extends FormBasicController {
	
	private GroupsAndRightsDataModel tableDataModel;
	private FormLink removeAllLink;
	
	private final RepositoryEntry resource;
	private final BGRightManager rightManager;
	private final BusinessGroupService businessGroupService;
	
	private static final String[] keys = {"ison"};
	private static final String[] values = {""};
	
	
	public GroupsAndRightsController(UserRequest ureq, WindowControl wControl, RepositoryEntry resource) {
		super(ureq, wControl, "right_list");
		
		rightManager = CoreSpringFactory.getImpl(BGRightManager.class);
		businessGroupService = CoreSpringFactory.getImpl(BusinessGroupService.class);
		this.resource = resource;
		
		initForm(ureq);
	}

	@Override
	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
		//group rights
		FlexiTableColumnModel tableColumnModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
		
		int colIndex = 0;
		tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.header.groups", colIndex++));
		tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.header.role", colIndex++));
		for(String right : CourseRights.getAvailableRights()) {
			tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel(right, colIndex++));
		}

		List<BGRightsOption> groupRights = loadModel();
		tableDataModel = new GroupsAndRightsDataModel(groupRights, tableColumnModel);
		uifactory.addTableElement(getWindowControl(), "rightList", tableDataModel, formLayout);
		
		FormLayoutContainer buttonsLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
		buttonsLayout.setRootForm(mainForm);
		formLayout.add("buttons", buttonsLayout);
		
		uifactory.addFormSubmitButton("save", buttonsLayout);
		removeAllLink = uifactory.addFormLink("remove.all", buttonsLayout, Link.BUTTON);
	}
	
	private List<BGRightsOption> loadModel() {
		List<BGRightsOption> options = new ArrayList<BGRightsOption>();
		List<BusinessGroup> groups = businessGroupService.findBusinessGroups(null, resource, 0, -1);
		
		List<BGRights> currentRights = rightManager.findBGRights(groups, resource.getOlatResource());
		Map<Long,BGRights> tutorToRightsMap = new HashMap<Long,BGRights>();
		Map<Long,BGRights> participantToRightsMap = new HashMap<Long,BGRights>();
		for(BGRights right:currentRights) {
			if(right.getRole() == BGRightsRole.tutor) {
				tutorToRightsMap.put(right.getBusinessGroupKey(), right);
			} else if(right.getRole() == BGRightsRole.participant) {
				participantToRightsMap.put(right.getBusinessGroupKey(), right);
			}	
		}

		for(BusinessGroup group:groups) {
			options.add(getRightsOption(group, tutorToRightsMap.get(group.getKey()), BGRightsRole.tutor));
			options.add(getRightsOption(group, participantToRightsMap.get(group.getKey()), BGRightsRole.participant));
		}
		return options;
	}
	
	private BGRightsOption getRightsOption(BusinessGroup group, BGRights r, BGRightsRole role) {
		BGRightsOption options = new BGRightsOption(group, role);
		fillCheckbox(options, r == null ? null : r.getRights());
		FormLink rmLink = uifactory.addFormLink("remove_" + UUID.randomUUID().toString(), "table.header.remove", "table.header.remove", flc, Link.LINK);
		rmLink.setUserObject(options);
		return options;
	}
	
	private void fillCheckbox(BGRightsOption groupRights, List<String> permissions) {
		List<BGRight> selections = new ArrayList<BGRight>();
		for(String permission : CourseRights.getAvailableRights()) {
			BGRight permissionEl = new BGRight(permission);
			boolean selected = permissions == null ? false : permissions.contains(permission);
			MultipleSelectionElement selection = createSelection(selected);
			permissionEl.setSelection(selection);
			selection.setUserObject(permissionEl);
			selections.add(permissionEl);
		}
		groupRights.setRightsEl(selections);
	}
	
	private MultipleSelectionElement createSelection(boolean selected) {
		String name = "cb" + UUID.randomUUID().toString().replace("-", "");
		MultipleSelectionElement selection = new MultipleSelectionElementImpl(name, Layout.horizontal);
		selection.setKeysAndValues(keys, values);
		flc.add(name, selection);
		selection.select(keys[0], selected);
		return selection;
	}
	
	@Override
	protected void doDispose() {
		//
	}

	@Override
	protected void formOK(UserRequest ureq) {
		doSaveChanges();
	}

	@Override
	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
		if (source == removeAllLink) {
			doRemoveAllRights();
		} else {
			super.formInnerEvent(ureq, source, event);
		}
	}
	
	private List<BusinessGroup> getGroups() {
		List<BusinessGroup> groups = new ArrayList<BusinessGroup>();
		for(BGRightsOption option:tableDataModel.getObjects()) {
			if(option.getRole() == BGRightsRole.tutor) {
				groups.add(option.getGroup());
			}
		}
		return groups;
	}
	
	private void doSaveChanges() {
		//collect group
		List<BGRightsOption> options = tableDataModel.getObjects();
		List<BusinessGroup> groups = getGroups();

		//collect current rights
		List<BGRights> currentRights = rightManager.findBGRights(groups, resource.getOlatResource());
		Map<Long,BGRights> tutorToRightsMap = new HashMap<Long,BGRights>();
		Map<Long,BGRights> participantToRightsMap = new HashMap<Long,BGRights>();
		for(BGRights right:currentRights) {
			if(right.getRole() == BGRightsRole.tutor) {
				tutorToRightsMap.put(right.getBusinessGroupKey(), right);
			} else if(right.getRole() == BGRightsRole.participant) {
				participantToRightsMap.put(right.getBusinessGroupKey(), right);
			}	
		}
		
		for(BGRightsOption option:options) {
			List<String> newPermissions = option.getSelectedPermissions();
			
			BGRights rights = null;
			if(option.getRole() == BGRightsRole.tutor) {
				rights = tutorToRightsMap.get(option.getGroupKey());
			} else if(option.getRole() == BGRightsRole.participant) {
				rights = participantToRightsMap.get(option.getGroupKey());
			}
			
			if(rights == null && newPermissions.isEmpty()) {
				continue;//nothing to do
			}
			List<String> currentPermissions = (rights == null ? Collections.<String>emptyList() : rights.getRights());
			if(newPermissions.containsAll(currentPermissions) && currentPermissions.containsAll(newPermissions)) {
				continue;//nothing to do
			}
			
			List<String> newPermissionsTmp = new ArrayList<String>(newPermissions);
			newPermissionsTmp.removeAll(currentPermissions);
			for(String newPermission:newPermissionsTmp) {
				rightManager.addBGRight(newPermission, option.getGroup(), resource.getOlatResource(), option.getRole());
			}
			
			currentPermissions.removeAll(newPermissions);
			for(String currentPermission:currentPermissions) {
				rightManager.removeBGRight(currentPermission, option.getGroup(), resource.getOlatResource(), option.getRole());
			}
		}
	}
	
	private void doRemoveAllRights() {
		List<BusinessGroup> groups = getGroups();
		rightManager.removeBGRights(groups, resource.getOlatResource());
		loadModel();
	}

	private class GroupsAndRightsDataModel extends DefaultTableDataModel<BGRightsOption> implements FlexiTableDataModel<BGRightsOption> {
		private FlexiTableColumnModel columnModel;
		
		public GroupsAndRightsDataModel(List<BGRightsOption> options, FlexiTableColumnModel columnModel) {
			super(options);
			this.columnModel = columnModel;
		}

		@Override
		public FlexiTableColumnModel getTableColumnModel() {
			return columnModel;
		}

		@Override
		public void setTableColumnModel(FlexiTableColumnModel tableColumnModel) {
			columnModel = tableColumnModel;
		}

		@Override
		public int getColumnCount() {
			return columnModel.getColumnCount();
		}

		@Override
		public Object getValueAt(int row, int col) {
			BGRightsOption groupRights = getObject(row);
			if(col == 0) {
				return groupRights.getGroupName();
			} else if (col == 1) {
				BGRightsRole role = groupRights.getRole();
				switch(role) {
					case tutor: return translate("tutor");
					case participant: return translate("participant");
				}
				return "";
			}
			
			//rights
			int rightPos = col - 2;
			return groupRights.getRightsEl().get(rightPos).getSelection();
		}

		@Override
		public Object createCopyWithEmptyList() {
			return new GroupsAndRightsDataModel(new ArrayList<BGRightsOption>(), columnModel);
		}
	}
	
	private static class BGRight {
		private final String permission;
		private MultipleSelectionElement selection;
		
		public BGRight(String permission) {
			this.permission = permission;
		}

		public MultipleSelectionElement getSelection() {
			return selection;
		}

		public void setSelection(MultipleSelectionElement selection) {
			this.selection = selection;
		}

		public String getPermission() {
			return permission;
		}
	}
	
	private static class BGRightsOption {
		private final BusinessGroup group;
		private final BGRightsRole role;
		
		private List<BGRight> rightsEl;
		
		public BGRightsOption(BusinessGroup group, BGRightsRole role) {
			this.group = group;
			this.role = role;
		}
		
		public String getGroupName() {
			return group.getName();
		}

		public Long getGroupKey() {
			return group.getKey();
		}
		
		public BusinessGroup getGroup() {
			return group;
		}
		
		public BGRightsRole getRole() {
			return role;
		}
		
		public List<String> getSelectedPermissions() {
			List<String> permissions = new ArrayList<String>(rightsEl.size());
			for(BGRight rightEl:rightsEl) {
				if(rightEl.getSelection().isAtLeastSelected(1)) {
					permissions.add(rightEl.getPermission());
				}	
			}
			return permissions;
		}
		
		public List<BGRight> getRightsEl() {
			return rightsEl;
		}
		
		public void setRightsEl(List<BGRight> rightsEl) {
			this.rightsEl = rightsEl;
		}
	}
}