/** * <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.admin.user.bulkChange; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.velocity.VelocityContext; import org.apache.velocity.context.Context; import org.olat.admin.user.groups.GroupSearchController; import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityManager; import org.olat.basesecurity.Constants; import org.olat.basesecurity.SecurityGroup; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.EscapeMode; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.impl.Form; import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiColumnModel; 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.form.flexible.impl.elements.table.FlexiTableDataModelImpl; import org.olat.core.gui.components.form.flexible.impl.elements.table.TextFlexiCellRenderer; import org.olat.core.gui.components.table.TableDataModel; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.wizard.BasicStep; import org.olat.core.gui.control.generic.wizard.PrevNextFinishConfig; import org.olat.core.gui.control.generic.wizard.Step; import org.olat.core.gui.control.generic.wizard.StepFormBasicController; import org.olat.core.gui.control.generic.wizard.StepFormController; import org.olat.core.gui.control.generic.wizard.StepsEvent; import org.olat.core.gui.control.generic.wizard.StepsRunContext; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.core.util.Util; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.group.ui.BusinessGroupFormController; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.UserPropertyHandler; /** * Description:<br> * last step presenting an overview of every change per selected user * which will be done after finish has been pressed * * <P> * Initial Date: 30.01.2008 <br> * * @author rhaag */ class UserBulkChangeStep02 extends BasicStep { static final String usageIdentifyer = UserBulkChangeStep00.class.getCanonicalName(); public List<UserPropertyHandler> userPropertyHandlers; private final UserBulkChangeManager ubcMan; private final BusinessGroupService businessGroupService; public UserBulkChangeStep02(UserRequest ureq) { super(ureq); setI18nTitleAndDescr("step2.description", null); setNextStep(Step.NOSTEP); businessGroupService = CoreSpringFactory.getImpl(BusinessGroupService.class); ubcMan = UserBulkChangeManager.getInstance(); } /** * @see org.olat.core.gui.control.generic.wizard.Step#getInitialPrevNextFinishConfig() */ public PrevNextFinishConfig getInitialPrevNextFinishConfig() { return new PrevNextFinishConfig(true, false, true); } /** * @see org.olat.core.gui.control.generic.wizard.Step#getStepController(org.olat.core.gui.UserRequest, * org.olat.core.gui.control.WindowControl, * org.olat.core.gui.control.generic.wizard.StepsRunContext, * org.olat.core.gui.components.form.flexible.impl.Form) */ public StepFormController getStepController(UserRequest ureq, WindowControl windowControl, StepsRunContext stepsRunContext, Form form) { StepFormController stepI = new UserBulkChangeStepForm02(ureq, windowControl, form, stepsRunContext); return stepI; } private final class UserBulkChangeStepForm02 extends StepFormBasicController { private FormLayoutContainer textContainer; public UserBulkChangeStepForm02(UserRequest ureq, WindowControl control, Form rootForm, StepsRunContext runContext) { super(ureq, control, rootForm, runContext, LAYOUT_VERTICAL, null); // use custom translator with fallback to user properties translator UserManager um = UserManager.getInstance(); Translator pt1 = um.getPropertyHandlerTranslator(getTranslator()); Translator pt2 = Util.createPackageTranslator(BusinessGroupFormController.class, ureq.getLocale(), pt1); Translator pt3 = Util.createPackageTranslator(GroupSearchController.class, ureq.getLocale(), pt2); setTranslator(pt3); flc.setTranslator(pt3); initForm(ureq); } @Override protected void doDispose() { // } @Override protected void formOK(UserRequest ureq) { fireEvent(ureq, StepsEvent.ACTIVATE_NEXT); } @Override protected boolean validateFormLogic(UserRequest ureq) { return true; } @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { FormLayoutContainer formLayoutVertical = FormLayoutContainer.createVerticalFormLayout("vertical", getTranslator()); formLayout.add(formLayoutVertical); setFormTitle("title"); List<List<String>> mergedDataChanges = new ArrayList<List<String>>(); textContainer = FormLayoutContainer.createCustomFormLayout("index", getTranslator(), this.velocity_root + "/step2.html"); formLayoutVertical.add(textContainer); boolean validChange = (Boolean) getFromRunContext("validChange"); textContainer.contextPut("validChange", validChange); if (!validChange) return; @SuppressWarnings("unchecked") List<Identity> selectedIdentities = (List<Identity>) getFromRunContext("identitiesToEdit"); @SuppressWarnings("unchecked") HashMap<String, String> attributeChangeMap = (HashMap<String, String>) getFromRunContext("attributeChangeMap"); @SuppressWarnings("unchecked") HashMap<String, String> roleChangeMap = (HashMap<String, String>) getFromRunContext("roleChangeMap"); Roles roles = ureq.getUserSession().getRoles(); boolean isAdministrativeUser = (roles.isAuthor() || roles.isGroupManager() || roles.isUserManager() || roles.isOLATAdmin()); userPropertyHandlers = UserManager.getInstance().getUserPropertyHandlersFor(usageIdentifyer, isAdministrativeUser); String[] securityGroups = { Constants.GROUP_USERMANAGERS, Constants.GROUP_GROUPMANAGERS, Constants.GROUP_AUTHORS, Constants.GROUP_ADMIN }; // loop over users to be edited: for (Identity identity : selectedIdentities) { List<String> userDataArray = new ArrayList<String>(); // add column for login userDataArray.add(identity.getName()); // add columns for password if (attributeChangeMap.containsKey(UserBulkChangeManager.PWD_IDENTIFYER)) { userDataArray.add(attributeChangeMap.get(UserBulkChangeManager.PWD_IDENTIFYER)); } else userDataArray.add("***"); // add column for language String userLanguage = identity.getUser().getPreferences().getLanguage(); if (attributeChangeMap.containsKey(UserBulkChangeManager.LANG_IDENTIFYER)) { String inputLanguage = attributeChangeMap.get(UserBulkChangeManager.LANG_IDENTIFYER); if (userLanguage.equals(inputLanguage)) { userDataArray.add(userLanguage); } else { userDataArray.add(decorateChangedCell(inputLanguage)); } } else { userDataArray.add(userLanguage); } Context vcContext = new VelocityContext(); // set all properties as context ubcMan.setUserContext(identity, vcContext); // loop for each property configured in // src/serviceconfig/org/olat/_spring/olat_userconfig.xml -> Key: // org.olat.admin.user.bulkChange.UserBulkChangeStep00 for (int k = 0; k < userPropertyHandlers.size(); k++) { String propertyName = userPropertyHandlers.get(k).getName(); String userValue = identity.getUser().getProperty(propertyName, null); String inputFieldValue = ""; if (attributeChangeMap.containsKey(propertyName)) { inputFieldValue = attributeChangeMap.get(propertyName); inputFieldValue = inputFieldValue.replace("$", "$!"); String evaluatedInputFieldValue = ubcMan.evaluateValueWithUserContext(inputFieldValue, vcContext); if (evaluatedInputFieldValue.equals(userValue)) { userDataArray.add(userValue); } else { // style italic: userDataArray.add(decorateChangedCell(evaluatedInputFieldValue)); } } else { // property has not been checked in step00 but should be in // overview-table userDataArray.add(userValue); } } // for // add columns with roles // loop over securityGroups and get result... for (String securityGroup : securityGroups) { String roleStatus = getRoleStatusForIdentity(identity, securityGroup, roleChangeMap); userDataArray.add(roleStatus); } // add column with status userDataArray.add(roleChangeMap.get("Status")); // add each user: mergedDataChanges.add(userDataArray); } TextFlexiCellRenderer textRenderer = new TextFlexiCellRenderer(EscapeMode.none); FlexiTableColumnModel tableColumnModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); // fixed fields: int colPos = 0; tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.user.login", colPos++)); tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel("form.name.pwd", colPos++)); tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel(true, "form.name.language", colPos++, false, null, FlexiColumnModel.ALIGNMENT_LEFT, textRenderer)); for (int j = 0; j < userPropertyHandlers.size(); j++) { UserPropertyHandler userPropertyHandler = userPropertyHandlers.get(j); tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel(true, userPropertyHandler.i18nColumnDescriptorLabelKey(), colPos++, false, null, FlexiColumnModel.ALIGNMENT_LEFT, textRenderer)); } tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel(true, "table.role.useradmin", colPos++, false, null, FlexiColumnModel.ALIGNMENT_LEFT, textRenderer)); tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel(true, "table.role.groupadmin", colPos++, false, null, FlexiColumnModel.ALIGNMENT_LEFT, textRenderer)); tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel(true, "table.role.author", colPos++, false, null, FlexiColumnModel.ALIGNMENT_LEFT, textRenderer)); tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel(true, "table.role.admin", colPos++, false, null, FlexiColumnModel.ALIGNMENT_LEFT, textRenderer)); tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel(true, "table.role.status", colPos++, false, null, FlexiColumnModel.ALIGNMENT_LEFT, textRenderer)); FlexiTableDataModel<List<String>> tableDataModel = new FlexiTableDataModelImpl<List<String>>(new OverviewModel(mergedDataChanges, colPos), tableColumnModel); uifactory.addTableElement(getWindowControl(), "newUsers", tableDataModel, getTranslator(), formLayoutVertical); Set<Long> allGroups = new HashSet<Long>(); @SuppressWarnings("unchecked") List<Long> ownGroups = (List<Long>) getFromRunContext("ownerGroups"); @SuppressWarnings("unchecked") List<Long> partGroups = (List<Long>) getFromRunContext("partGroups"); allGroups.addAll(ownGroups); allGroups.addAll(partGroups); @SuppressWarnings("unchecked") List<Long> mailGroups = (List<Long>) getFromRunContext("mailGroups"); if (allGroups.size() != 0) { uifactory.addSpacerElement("space", formLayout, true); uifactory.addStaticTextElement("add.to.groups", "", formLayout); FlexiTableColumnModel groupColumnModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); groupColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.group.name", 0)); groupColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel("description", 1)); groupColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.user.role", 2)); groupColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel("send.email", 3)); List<BusinessGroup> groups = businessGroupService.loadBusinessGroups(allGroups); TableDataModel<BusinessGroup> model = new GroupAddOverviewModel(groups, ownGroups, partGroups, mailGroups, getTranslator()); FlexiTableDataModel<BusinessGroup> groupDataModel = new FlexiTableDataModelImpl<BusinessGroup>(model, groupColumnModel); uifactory.addTableElement(getWindowControl(), "groupOverview", groupDataModel, getTranslator(), formLayout); } } /** * compare roles of given identity with changes to be applied from * wizard-step 01 * * @param identity * @param securityGroup * @param roleChangeMap * @return */ private String getRoleStatusForIdentity(Identity identity, String securityGroup, HashMap<String, String> roleChangeMap) { BaseSecurity secMgr = BaseSecurityManager.getInstance(); SecurityGroup secGroup = secMgr.findSecurityGroupByName(securityGroup); Boolean isInGroup = secMgr.isIdentityInSecurityGroup(identity, secGroup); String thisRoleAction = ""; if (roleChangeMap.containsKey(securityGroup)) { thisRoleAction = roleChangeMap.get(securityGroup); } else return isInGroup.toString(); if ((isInGroup && thisRoleAction.equals("add")) || (!isInGroup && thisRoleAction.equals("remove"))) { return isInGroup.toString(); } else { isInGroup = !isInGroup; //invert to represent the new state return decorateChangedCell(isInGroup); } } private String decorateChangedCell(Object val) { return "<span class='o_userbulk_changedcell'><i class='o_icon o_icon_new'> </i> " + val.toString() + "</span>"; } } }