diff --git a/src/main/java/org/olat/admin/securitygroup/gui/multi/UsersToGroupWizardStep01.java b/src/main/java/org/olat/admin/securitygroup/gui/multi/UsersToGroupWizardStep01.java index 043c3033157eb6adaf75d55d424d3825df8c2a1d..3f1eb2fc21f37cab8e780028d1058b02319100eb 100644 --- a/src/main/java/org/olat/admin/securitygroup/gui/multi/UsersToGroupWizardStep01.java +++ b/src/main/java/org/olat/admin/securitygroup/gui/multi/UsersToGroupWizardStep01.java @@ -24,6 +24,7 @@ import org.olat.core.gui.components.form.flexible.impl.Form; 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.StepFormController; import org.olat.core.gui.control.generic.wizard.StepsRunContext; import org.olat.core.util.mail.MailTemplate; @@ -47,7 +48,7 @@ public class UsersToGroupWizardStep01 extends BasicStep { setI18nTitleAndDescr("import.title.select", null); if(mailDefaultTemplate == null) { - setNextStep(BasicStep.NOSTEP); + setNextStep(Step.NOSTEP); } else { setNextStep(new UsersToGroupWizardStep02(ureq)); } diff --git a/src/main/java/org/olat/admin/user/UserSearchFlexiController.java b/src/main/java/org/olat/admin/user/UserSearchFlexiController.java index 10282ff03cc2a4b5358cd407871955ee88a5b3ec..3abdc12164234d998a6798710ae717660940d654 100644 --- a/src/main/java/org/olat/admin/user/UserSearchFlexiController.java +++ b/src/main/java/org/olat/admin/user/UserSearchFlexiController.java @@ -102,7 +102,8 @@ public class UserSearchFlexiController extends FlexiAutoCompleterController { private static final String usageIdentifyer = UserTableDataModel.class.getCanonicalName(); - private FormLink backLink, searchButton; + private FormLink backLink; + private FormLink searchButton; private TextElement loginEl; private Map <String,FormItem>propFormItems; private FlexiTableElement tableEl; diff --git a/src/main/java/org/olat/basesecurity/BaseSecurity.java b/src/main/java/org/olat/basesecurity/BaseSecurity.java index e2257501af7bbdf729dc75824f8aa5dbe766dc6b..4cb050a7a4eb5d7153d366dcd98cfa2129068c33 100644 --- a/src/main/java/org/olat/basesecurity/BaseSecurity.java +++ b/src/main/java/org/olat/basesecurity/BaseSecurity.java @@ -105,8 +105,8 @@ public interface BaseSecurity { /** * Specialized method to import identities in courses, groups... The query * search in the legacy name of identity, in authentication user name, - * concat first and last name and institutional number. It's all case - * insensitive. + * concat first and last name, email, institutional number, institutional + * email. It's all case insensitive. * * @param identityNames A list of names * @return A list of identities diff --git a/src/main/java/org/olat/basesecurity/manager/IdentityDAO.java b/src/main/java/org/olat/basesecurity/manager/IdentityDAO.java index 580ada2aadb3177f662955ffc862085a9f83808f..e428dcd1b8b7aeb1013cee271508ab014c7202a9 100644 --- a/src/main/java/org/olat/basesecurity/manager/IdentityDAO.java +++ b/src/main/java/org/olat/basesecurity/manager/IdentityDAO.java @@ -81,6 +81,8 @@ public class IdentityDAO { .append(" where lower(ident.name) in (:names)") .append(" or lower(auth.authusername) in (:names)") .append(" or lower(concat(user.firstName,' ', user.lastName)) in (:names)") + .append(" or lower(user.email) in (:names)") + .append(" or lower(user.institutionalEmail) in (:names)") .append(" or lower(user.institutionalUserIdentifier) in (:names)"); List<String> loweredIdentityNames = names.stream() @@ -131,6 +133,16 @@ public class IdentityDAO { if(names.contains(fullName.toLowerCase())) { namedIdentity.addName(fullName); } + + if(StringHelper.containsNonWhitespace(user.getEmail()) + && names.contains(user.getEmail().toLowerCase())) { + namedIdentity.addName(user.getEmail()); + } + + if(StringHelper.containsNonWhitespace(user.getInstitutionalEmail()) + && names.contains(user.getInstitutionalEmail().toLowerCase())) { + namedIdentity.addName(user.getInstitutionalEmail()); + } } public void setIdentityLastLogin(IdentityRef identity, Date lastLogin) { diff --git a/src/main/java/org/olat/core/gui/control/generic/wizard/DefaultStepsRunContext.java b/src/main/java/org/olat/core/gui/control/generic/wizard/DefaultStepsRunContext.java index 335a66ddf5191ae7af87bb884608bf764c490a82..f6261c749305a3f6a3f9c2b929c685acf147afdb 100644 --- a/src/main/java/org/olat/core/gui/control/generic/wizard/DefaultStepsRunContext.java +++ b/src/main/java/org/olat/core/gui/control/generic/wizard/DefaultStepsRunContext.java @@ -47,4 +47,8 @@ public class DefaultStepsRunContext implements StepsRunContext { return context.containsKey(key); } + @Override + public void remove(String key) { + context.remove(key); + } } diff --git a/src/main/java/org/olat/core/gui/control/generic/wizard/StepFormBasicController.java b/src/main/java/org/olat/core/gui/control/generic/wizard/StepFormBasicController.java index 0da1728bdd6f098ca963e33d7e0546216902b489..60706f06d74c1961084d6eb16e4ca509b8478777 100644 --- a/src/main/java/org/olat/core/gui/control/generic/wizard/StepFormBasicController.java +++ b/src/main/java/org/olat/core/gui/control/generic/wizard/StepFormBasicController.java @@ -25,6 +25,8 @@ */ package org.olat.core.gui.control.generic.wizard; +import java.util.List; + import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.form.flexible.FormItem; @@ -94,15 +96,26 @@ public abstract class StepFormBasicController extends FormBasicController implem runContext = null; } - protected void addToRunContext(String key, Object value){ + protected void addToRunContext(String key, Object value) { runContext.put(key, value); } - protected boolean containsRunContextKey(String key){ + + protected void removeFromRunContext(String key) { + runContext.remove(key); + } + + protected boolean containsRunContextKey(String key) { return runContext.containsKey(key); } - protected Object getFromRunContext(String key){ + + protected Object getFromRunContext(String key) { return runContext.get(key); } + + @SuppressWarnings({ "unused", "unchecked" }) + protected <T> List<T> getListFromRunContext(String key, Class<T> resultClass) { + return (List<T>)runContext.get(key); + } public void back() { diff --git a/src/main/java/org/olat/core/gui/control/generic/wizard/StepsRunContext.java b/src/main/java/org/olat/core/gui/control/generic/wizard/StepsRunContext.java index a1040695c81b9876bbecdc58f79d9f7f9995bcde..3a04b471e10e06e231d3e65d40db87c7f72fe7c4 100644 --- a/src/main/java/org/olat/core/gui/control/generic/wizard/StepsRunContext.java +++ b/src/main/java/org/olat/core/gui/control/generic/wizard/StepsRunContext.java @@ -31,23 +31,11 @@ package org.olat.core.gui.control.generic.wizard; */ public interface StepsRunContext { - /** - * - * @param key - * @param value - */ public void put(String key, Object value); - /** - * - * @param key - * @return - */ + public Object get(String key); - /** - * - * @param key - * @return - */ public boolean containsKey(String key); + + public void remove(String key); } diff --git a/src/main/java/org/olat/course/member/wizard/ImportMemberByUsernamesController.java b/src/main/java/org/olat/course/member/wizard/ImportMemberByUsernamesController.java index c23cc7d13d4be9a573a091a2584105592ee246e5..c7a5ef0f8da70cc58a395b3d6686e50f9578da12 100644 --- a/src/main/java/org/olat/course/member/wizard/ImportMemberByUsernamesController.java +++ b/src/main/java/org/olat/course/member/wizard/ImportMemberByUsernamesController.java @@ -19,54 +19,254 @@ */ package org.olat.course.member.wizard; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.olat.admin.user.UserTableDataModel; +import org.olat.basesecurity.BaseSecurity; +import org.olat.basesecurity.BaseSecurityModule; +import org.olat.basesecurity.OrganisationRoles; +import org.olat.basesecurity.OrganisationService; +import org.olat.basesecurity.model.FindNamedIdentity; 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.FlexiTableElement; +import org.olat.core.gui.components.form.flexible.elements.FormLink; import org.olat.core.gui.components.form.flexible.elements.TextElement; import org.olat.core.gui.components.form.flexible.impl.Form; +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.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.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.wizard.StepFormBasicController; import org.olat.core.gui.control.generic.wizard.StepsEvent; import org.olat.core.gui.control.generic.wizard.StepsRunContext; +import org.olat.core.id.Identity; +import org.olat.user.UserManager; +import org.olat.user.propertyhandlers.UserPropertyHandler; +import org.springframework.beans.factory.annotation.Autowired; /** * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ public class ImportMemberByUsernamesController extends StepFormBasicController { + + private static final String usageIdentifyer = UserTableDataModel.class.getCanonicalName(); private TextElement idata; + private FlexiTableElement tableEl; + private ImportMemberOverviewDataModel userTableModel; + + private FormLink backLink; + private FormLayoutContainer inputContainer; + private FormLayoutContainer tableContainer; + + private boolean isAdministrativeUser; + private final List<Identity> anonymousUsers; + + private List<String> notFoundNames; + private List<Identity> identitiesList; + + @Autowired + private UserManager userManager; + @Autowired + private BaseSecurity securityManager; + @Autowired + private BaseSecurityModule securityModule; + @Autowired + private OrganisationService organisationService; public ImportMemberByUsernamesController(UserRequest ureq, WindowControl wControl, Form rootForm, StepsRunContext runContext) { - super(ureq, wControl, rootForm, runContext, LAYOUT_DEFAULT, null); + super(ureq, wControl, rootForm, runContext, LAYOUT_BAREBONE, null); + setTranslator(userManager.getPropertyHandlerTranslator(getTranslator())); + anonymousUsers = organisationService.getIdentitiesWithRole(OrganisationRoles.guest); + isAdministrativeUser = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles()); initForm (ureq); } - public boolean validate() { - return !idata.isEmpty("form.legende.mandatory"); + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + // input field + inputContainer = FormLayoutContainer.createDefaultFormLayout("input", getTranslator()); + formLayout.add(inputContainer); + + idata = uifactory.addTextAreaElement("addusers", "form.addusers", -1, 15, 40, true, false, " ", inputContainer); + idata.setElementCssClass("o_sel_user_import"); + idata.setExampleKey ("form.names.example", null); + + // table for duplicates + String page = velocity_root + "/warn_duplicates.html"; + tableContainer = FormLayoutContainer.createCustomFormLayout("table", getTranslator(), page); + formLayout.add(tableContainer); + tableContainer.setVisible(false); + + // user search form + backLink = uifactory.addFormLink("back", tableContainer); + backLink.setIconLeftCSS("o_icon o_icon_back"); + + //add the table + FlexiTableColumnModel tableColumnModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); + int colIndex = 0; + List<UserPropertyHandler> userPropertyHandlers = userManager.getUserPropertyHandlersFor(usageIdentifyer, isAdministrativeUser); + List<UserPropertyHandler> resultingPropertyHandlers = new ArrayList<>(); + // followed by the users fields + for (int i = 0; i < userPropertyHandlers.size(); i++) { + UserPropertyHandler userPropertyHandler = userPropertyHandlers.get(i); + boolean visible = UserManager.getInstance().isMandatoryUserProperty(usageIdentifyer , userPropertyHandler); + if(visible) { + resultingPropertyHandlers.add(userPropertyHandler); + tableColumnModel.addFlexiColumnModel(new DefaultFlexiColumnModel(userPropertyHandler.i18nColumnDescriptorLabelKey(), colIndex++)); + } + } + + userTableModel = new ImportMemberOverviewDataModel(resultingPropertyHandlers, getLocale(), tableColumnModel); + tableEl = uifactory.addTableElement(getWindowControl(), "users", userTableModel, 100, false, getTranslator(), tableContainer); + tableEl.setCustomizeColumns(false); + tableEl.setMultiSelect(true); + tableEl.setSelectAllEnable(true); } - public String getLoginsString() { - return idata.getValue(); + @Override + protected void doDispose() { + // } - + @Override protected void formOK(UserRequest ureq) { - String logins = idata.getValue(); - addToRunContext("logins", logins); - fireEvent(ureq, StepsEvent.ACTIVATE_NEXT); + // } @Override - protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - idata = uifactory.addTextAreaElement("addusers", "form.addusers", -1, 15, 40, true, false, " ", formLayout); - idata.setElementCssClass("o_sel_user_import"); - idata.setExampleKey ("form.names.example", null); + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(backLink == source) { + doBackToInput(); + } + super.formInnerEvent(ureq, source, event); } @Override - protected void doDispose() { - // + protected void formNext(UserRequest ureq) { + String logins = idata.getValue(); + if(tableContainer.isVisible()) { + selectDuplicates(); + addToRunContext("keyIdentities", new ArrayList<>(identitiesList)); + addToRunContext("notFounds", notFoundNames); + fireEvent(ureq, StepsEvent.ACTIVATE_NEXT); + } else if(processInput(logins)) { + tableContainer.setVisible(true); + inputContainer.setVisible(false); + } else { + addToRunContext("keyIdentities", new ArrayList<>(identitiesList)); + addToRunContext("notFounds", notFoundNames); + fireEvent(ureq, StepsEvent.ACTIVATE_NEXT); + } + } + + private void doBackToInput() { + tableContainer.setVisible(false); + inputContainer.setVisible(true); + identitiesList = null; + } + + private void selectDuplicates() { + List<Identity> selectedIdentities = new ArrayList<>(); + for(Integer index:tableEl.getMultiSelectedIndex()) { + Identity identity = userTableModel.getObject(index.intValue()); + if(identity != null) { + selectedIdentities.add(identity); + } + } + identitiesList.addAll(selectedIdentities); + } + + /** + * + * @param inp The text input + * @return true if duplicates found + */ + private boolean processInput(String inp) { + List<String> identList = getLines(inp); + Set<String> identListLowercase = identList.stream() + .map(String::toLowerCase) + .collect(Collectors.toSet()); + + notFoundNames = new ArrayList<>(); + Map<String, Set<Identity>> duplicates = new HashMap<>(); + Set<Identity> okSet = new HashSet<>(); + + // search by names, institutional identifier, first + last names, authentication user names + List<FindNamedIdentity> identities = securityManager.findIdentitiesBy(identList); + for(FindNamedIdentity identity:identities) { + identListLowercase.removeAll(identity.getNamesLowerCase()); + if(!validIdentity(identity.getIdentity())) { + notFoundNames.add(identity.getFirstFoundName()); + } else if (!okSet.contains(identity.getIdentity())) { + okSet.add(identity.getIdentity()); + } + + for(String name:identity.getNamesLowerCase()) { + Set<Identity> ids = duplicates.computeIfAbsent(name, n -> new HashSet<>()); + ids.add(identity.getIdentity()); + } + } + + notFoundNames.addAll(identListLowercase); + return processDuplicates(okSet, duplicates); + } + + private boolean processDuplicates(Set<Identity> okSet, Map<String, Set<Identity>> duplicates) { + Set<Identity> duplicatesSet = new HashSet<>(); + StringBuilder sb = new StringBuilder(); + for(Map.Entry<String,Set<Identity>> entry:duplicates.entrySet()) { + if(entry.getValue().size() > 1) { + if(sb.length() > 0) sb.append(", "); + sb.append(entry.getKey()); + duplicatesSet.addAll(entry.getValue()); + } + } + + okSet.removeAll(duplicatesSet); + + identitiesList = new ArrayList<>(okSet); + + if(sb.length() > 0) { + tableContainer.contextPut("duplicatesMsg", translate("warn.duplicates.names", sb.toString())); + tableContainer.setVisible(true); + inputContainer.setVisible(false); + + userTableModel.setObjects(new ArrayList<>(duplicatesSet)); + tableEl.reset(true, true, true); + return true; + } + return false; + } + + private List<String> getLines(String inp) { + List<String> identList = new ArrayList<>(); + String[] lines = inp.split("\r?\n"); + for (int i = 0; i < lines.length; i++) { + String username = lines[i].trim(); + if(username.length() > 0) { + identList.add(username); + } + } + return identList; + } + + private boolean validIdentity(Identity ident) { + return ident != null + && ident.getStatus().compareTo(Identity.STATUS_VISIBLE_LIMIT) < 0 + && !anonymousUsers.contains(ident); } } \ No newline at end of file diff --git a/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewDataModel.java b/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewDataModel.java index bde98ca39aef13e7f251260e50a4a91296c9aea6..b3340ce65bb1dba4fc509bec1adc1b9d74e9a70d 100644 --- a/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewDataModel.java +++ b/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewDataModel.java @@ -38,6 +38,11 @@ public class ImportMemberOverviewDataModel extends DefaultTableDataModel<Identit private FlexiTableColumnModel columnModel; private final List<UserPropertyHandler> userPropertyHandlers; + public ImportMemberOverviewDataModel(List<UserPropertyHandler> userPropertyHandlers, Locale locale, + FlexiTableColumnModel columnModel) { + this(new ArrayList<>(), userPropertyHandlers, locale, columnModel); + } + public ImportMemberOverviewDataModel(List<Identity> identities, List<UserPropertyHandler> userPropertyHandlers, Locale locale, FlexiTableColumnModel columnModel) { super(identities); diff --git a/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java b/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java index 7504e49fe0e7d575d6fad4422c7abc87c61774ae..618baa969196a062fa164796aec71bd58e7ce682 100644 --- a/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java +++ b/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java @@ -20,19 +20,14 @@ package org.olat.course.member.wizard; import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; import org.olat.admin.user.UserTableDataModel; -import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityModule; import org.olat.basesecurity.OrganisationRoles; import org.olat.basesecurity.OrganisationService; -import org.olat.basesecurity.model.FindNamedIdentity; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; @@ -46,9 +41,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.wizard.StepFormBasicController; 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.UserConstants; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.UserPropertyHandler; import org.springframework.beans.factory.annotation.Autowired; @@ -61,44 +54,31 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr private static final String usageIdentifyer = UserTableDataModel.class.getCanonicalName(); - private FlexiTableElement tableEl; - private ImportMemberOverviewDataModel userTableModel; - private List<Identity> oks; - private List<String> notfounds; + private List<String> notFounds; private boolean isAdministrativeUser; private final List<Identity> anonymousUsers; - private Map<String,Set<Identity>> duplicates = new HashMap<>(); - @Autowired private UserManager userManager; @Autowired - private BaseSecurity securityManager; - @Autowired private BaseSecurityModule securityModule; @Autowired private OrganisationService organisationService; public ImportMemberOverviewIdentitiesController(UserRequest ureq, WindowControl wControl, Form rootForm, StepsRunContext runContext) { super(ureq, wControl, rootForm, runContext, LAYOUT_VERTICAL, null); - + setTranslator(userManager.getPropertyHandlerTranslator(getTranslator())); anonymousUsers = organisationService.getIdentitiesWithRole(OrganisationRoles.guest); isAdministrativeUser = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles()); oks = null; - if(containsRunContextKey("logins")) { - String logins = (String)runContext.get("logins"); - loadModel(logins); - } else if(containsRunContextKey("keys")) { - @SuppressWarnings("unchecked") - List<String> keys = (List<String>)runContext.get("keys"); - loadModel(keys); - } else if(containsRunContextKey("keyIdentities")) { - @SuppressWarnings("unchecked") - List<Identity> keys = (List<Identity>)runContext.get("keyIdentities"); - loadModelByIdentities(keys); + notFounds = getListFromRunContext("notFounds", String.class); + if(notFounds == null) { + notFounds = new ArrayList<>(); } + List<Identity> keys = getListFromRunContext("keyIdentities", Identity.class); + loadModelByIdentities(keys); initForm (ureq); } @@ -106,14 +86,14 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { formLayout.setElementCssClass("o_sel_user_import_overview"); - if(notfounds != null && !notfounds.isEmpty()) { + if(notFounds != null && !notFounds.isEmpty()) { String page = velocity_root + "/warn_notfound.html"; FormLayoutContainer warnLayout = FormLayoutContainer.createCustomFormLayout("warnNotFounds", getTranslator(), page); warnLayout.setRootForm(mainForm); formLayout.add(warnLayout); StringBuilder sb = new StringBuilder(); - for(String notfound:notfounds) { + for(String notfound:notFounds) { if(sb.length() > 0) sb.append(", "); sb.append(notfound); } @@ -122,23 +102,6 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr warnLayout.contextPut("notFounds", msg); } - StringBuilder sb = new StringBuilder(); - for(Map.Entry<String,Set<Identity>> entry:duplicates.entrySet()) { - if(entry.getValue().size() > 1) { - if(sb.length() > 0) sb.append(", "); - sb.append(entry.getKey()); - } - } - - - if(sb.length() > 0) { - String page = velocity_root + "/warn_duplicates.html"; - FormLayoutContainer warnLayout = FormLayoutContainer.createCustomFormLayout("warnNotFounds", getTranslator(), page); - warnLayout.setRootForm(mainForm); - formLayout.add(warnLayout); - warnLayout.contextPut("duplicatesMsg", translate("warn.duplicates.names", sb.toString())); - } - //add the table FlexiTableColumnModel tableColumnModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); int colIndex = 0; @@ -154,42 +117,18 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr } } - Translator myTrans = userManager.getPropertyHandlerTranslator(getTranslator()); - userTableModel = new ImportMemberOverviewDataModel(oks, resultingPropertyHandlers, getLocale(), tableColumnModel); - tableEl = uifactory.addTableElement(getWindowControl(), "users", userTableModel, myTrans, formLayout); + ImportMemberOverviewDataModel userTableModel = new ImportMemberOverviewDataModel(oks, resultingPropertyHandlers, getLocale(), tableColumnModel); + FlexiTableElement tableEl = uifactory.addTableElement(getWindowControl(), "users", userTableModel, getTranslator(), formLayout); tableEl.setCustomizeColumns(false); - //TODO OO-4545 - /* - tableEl.setMultiSelect(true); - tableEl.setSelectAllEnable(true); - tableEl.selectAll(); - */ - } - - private void loadModel(List<String> keys) { - notfounds = new ArrayList<>(); - - Set<Identity> okSet = new HashSet<>(); - for (String identityKey : keys) { - Identity ident = securityManager.loadIdentityByKey(Long.parseLong(identityKey)); - if (!validIdentity(ident)) { // not found, add to not-found-list - notfounds.add(identityKey); - } else if (!okSet.contains(ident)) { - okSet.add(ident); - } - } - oks = new ArrayList<>(okSet); } - private void loadModelByIdentities(List<Identity> keys) { - notfounds = new ArrayList<>(); - + private void loadModelByIdentities(List<Identity> identities) { Set<Identity> okSet = new HashSet<>(); - for (Identity ident : keys) { + for (Identity ident : identities) { if (!validIdentity(ident)) { String fullname = userManager.getUserDisplayName(ident); if(fullname != null) { - notfounds.add(fullname); + notFounds.add(fullname); } } else if (!okSet.contains(ident)) { okSet.add(ident); @@ -198,76 +137,6 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr oks = new ArrayList<>(okSet); } - private void loadModel(String inp) { - oks = new ArrayList<>(); - notfounds = new ArrayList<>(); - duplicates.clear(); - - Set<Identity> okSet = new HashSet<>(); - List<String> identList = new ArrayList<>(); - String[] lines = inp.split("\r?\n"); - for (int i = 0; i < lines.length; i++) { - String username = lines[i].trim(); - if(username.length() > 0) { - identList.add(username); - } - } - - // make a lower case copy of identList for processing username and email - Collection<String> identListLowercase = new HashSet<>(identList.size()); - for (String ident:identList) { - identListLowercase.add(ident.toLowerCase()); - } - - // search by names, institutional identifier, first + last names, authentication user names - List<FindNamedIdentity> identities = securityManager.findIdentitiesBy(identList); - for(FindNamedIdentity identity:identities) { - identListLowercase.removeAll(identity.getNamesLowerCase()); - if(!validIdentity(identity.getIdentity())) { - notfounds.add(identity.getFirstFoundName()); - } else if (!okSet.contains(identity.getIdentity())) { - okSet.add(identity.getIdentity()); - } - - for(String name:identity.getNamesLowerCase()) { - Set<Identity> ids = duplicates.computeIfAbsent(name, n -> new HashSet<>()); - ids.add(identity.getIdentity()); - } - } - - //search by email, case insensitive - List<String> emailListLowercase = new ArrayList<>(identList.size()); - for (String ident:identList) { - if(ident.indexOf('@') > 0) { - emailListLowercase.add(ident.toLowerCase()); - } - } - - List<Identity> mailIdentities = userManager.findIdentitiesByEmail(emailListLowercase); - for(Identity identity:mailIdentities) { - String email = identity.getUser().getProperty(UserConstants.EMAIL, null); - if(email != null && identListLowercase.remove(email.toLowerCase())) { - duplicates.computeIfAbsent(email.toLowerCase(), n -> new HashSet<>()).add(identity); - } - String institutEmail = identity.getUser().getProperty(UserConstants.INSTITUTIONALEMAIL, null); - if(institutEmail != null && identListLowercase.remove(institutEmail.toLowerCase())) { - duplicates.computeIfAbsent(institutEmail.toLowerCase(), n -> new HashSet<>()).add(identity); - } - if(!validIdentity(identity)) { - if(email != null) { - notfounds.remove(email); - } else if(institutEmail != null) { - notfounds.remove(institutEmail); - } - } else if (!okSet.contains(identity)) { - okSet.add(identity); - } - } - - notfounds.addAll(identListLowercase); - oks = new ArrayList<>(okSet); - } - private boolean validIdentity(Identity ident) { return ident != null && ident.getStatus().compareTo(Identity.STATUS_VISIBLE_LIMIT) < 0 @@ -280,17 +149,11 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr @Override protected void formNext(UserRequest ureq) { - //TODO OO-4545 - /* - List<Identity> selectedOks = new ArrayList<>(oks.size()); - for(Integer index:tableEl.getMultiSelectedIndex()) { - Identity selected = userTableModel.getObject(index.intValue()); - if(selected != null) { - selectedOks.add(selected); - } + if(notFounds == null || notFounds.isEmpty()) { + removeFromRunContext("notFounds"); + } else { + addToRunContext("notFounds", notFounds); } - addToRunContext("members", selectedOks); - */ addToRunContext("members", oks); fireEvent(ureq, StepsEvent.ACTIVATE_NEXT); } diff --git a/src/main/java/org/olat/course/member/wizard/_content/warn_duplicates.html b/src/main/java/org/olat/course/member/wizard/_content/warn_duplicates.html index a6722d64934e2845f56e7f7d855b812f7c59d539..c626d072b81d656f7d4d943b127d68f1496f6ffc 100644 --- a/src/main/java/org/olat/course/member/wizard/_content/warn_duplicates.html +++ b/src/main/java/org/olat/course/member/wizard/_content/warn_duplicates.html @@ -1,4 +1,6 @@ +<div>$r.render("back")</div> <div class="o_warning"> $duplicatesMsg<br> $r.translate("warn.duplicates.select") -</div> \ No newline at end of file +</div> +$r.render("users") \ No newline at end of file diff --git a/src/main/java/org/olat/user/UserImpl.java b/src/main/java/org/olat/user/UserImpl.java index 684883b401f811ae9f55a2cb9e59f845dc835120..8d5f39d8337e049c77172c0ae230546db55d85d8 100644 --- a/src/main/java/org/olat/user/UserImpl.java +++ b/src/main/java/org/olat/user/UserImpl.java @@ -74,7 +74,7 @@ import org.olat.user.propertyhandlers.UserPropertyHandler; */ @Entity @Table(name="o_user") -public class UserImpl implements Persistable, User { +public class UserImpl implements User { private static final long serialVersionUID = -2872102058369727753L; private static final Logger log = Tracing.createLoggerFor(UserImpl.class);