com.evolveum.midpoint.web.page.admin.users.PageUsers.java Source code

Java tutorial

Introduction

Here is the source code for com.evolveum.midpoint.web.page.admin.users.PageUsers.java

Source

/*
 * Copyright (c) 2010-2013 Evolveum
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.evolveum.midpoint.web.page.admin.users;

import com.evolveum.midpoint.model.api.ModelExecuteOptions;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismReference;
import com.evolveum.midpoint.prism.delta.ChangeType;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.match.PolyStringNormMatchingRule;
import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer;
import com.evolveum.midpoint.prism.query.*;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.RetrieveOption;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.security.api.AuthorizationConstants;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.application.AuthorizationAction;
import com.evolveum.midpoint.web.application.PageDescriptor;
import com.evolveum.midpoint.web.component.BasicSearchPanel;
import com.evolveum.midpoint.web.component.DropDownMultiChoice;
import com.evolveum.midpoint.web.component.data.ObjectDataProvider;
import com.evolveum.midpoint.web.component.data.TablePanel;
import com.evolveum.midpoint.web.component.data.column.*;
import com.evolveum.midpoint.web.component.dialog.ConfirmationDialog;
import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItem;
import com.evolveum.midpoint.web.component.util.LoadableModel;
import com.evolveum.midpoint.web.page.admin.configuration.component.HeaderMenuAction;
import com.evolveum.midpoint.web.page.admin.users.component.ExecuteChangeOptionsDto;
import com.evolveum.midpoint.web.page.admin.users.component.ExecuteChangeOptionsPanel;
import com.evolveum.midpoint.web.page.admin.users.dto.UserListItemDto;
import com.evolveum.midpoint.web.page.admin.users.dto.UsersDto;
import com.evolveum.midpoint.web.session.UsersStorage;
import com.evolveum.midpoint.web.util.OnePageParameterEncoder;
import com.evolveum.midpoint.web.util.WebMiscUtil;
import com.evolveum.midpoint.web.util.WebModelUtils;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.apache.commons.lang.StringUtils;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author lazyman
 */
@PageDescriptor(url = "/admin/users", action = {
        @AuthorizationAction(actionUri = PageAdminUsers.AUTH_USERS_ALL, label = PageAdminUsers.AUTH_USERS_ALL_LABEL, description = PageAdminUsers.AUTH_USERS_ALL_DESCRIPTION),
        @AuthorizationAction(actionUri = AuthorizationConstants.NS_AUTHORIZATION
                + "#users", label = "PageUsers.auth.users.label", description = "PageUsers.auth.users.description") })
public class PageUsers extends PageAdminUsers {

    private static final Trace LOGGER = TraceManager.getTrace(PageUsers.class);
    private static final String DOT_CLASS = PageUsers.class.getName() + ".";
    private static final String OPERATION_DELETE_USERS = DOT_CLASS + "deleteUsers";
    private static final String OPERATION_DELETE_USER = DOT_CLASS + "deleteUser";
    private static final String OPERATION_DISABLE_USERS = DOT_CLASS + "disableUsers";
    private static final String OPERATION_DISABLE_USER = DOT_CLASS + "disableUser";
    private static final String OPERATION_ENABLE_USERS = DOT_CLASS + "enableUsers";
    private static final String OPERATION_ENABLE_USER = DOT_CLASS + "enableUser";
    private static final String OPERATION_RECONCILE_USERS = DOT_CLASS + "reconcileUsers";
    private static final String OPERATION_RECONCILE_USER = DOT_CLASS + "reconcileUser";
    private static final String DIALOG_CONFIRM_DELETE = "confirmDeletePopup";

    private static final String ID_EXECUTE_OPTIONS = "executeOptions";
    private static final String ID_MAIN_FORM = "mainForm";
    private static final String ID_TABLE = "table";
    private static final String ID_SEARCH_FORM = "searchForm";
    private static final String ID_BASIC_SEARCH = "basicSearch";
    private static final String ID_SEARCH_TYPE = "searchType";

    private UserListItemDto singleDelete;
    private LoadableModel<UsersDto> model;
    private LoadableModel<ExecuteChangeOptionsDto> executeOptionsModel;

    public PageUsers() {
        model = new LoadableModel<UsersDto>(false) {

            @Override
            public UsersDto load() {
                UsersStorage storage = getSessionStorage().getUsers();
                UsersDto dto = storage.getUsersSearch();
                if (dto == null) {
                    dto = new UsersDto();
                }

                return dto;
            }
        };

        executeOptionsModel = new LoadableModel<ExecuteChangeOptionsDto>(false) {

            @Override
            protected ExecuteChangeOptionsDto load() {
                return new ExecuteChangeOptionsDto();
            }
        };
        initLayout();
    }

    private void initLayout() {
        Form mainForm = new Form(ID_MAIN_FORM);
        add(mainForm);

        add(new ConfirmationDialog(DIALOG_CONFIRM_DELETE,
                createStringResource("pageUsers.dialog.title.confirmDelete"), createDeleteConfirmString()) {

            @Override
            public void yesPerformed(AjaxRequestTarget target) {
                close(target);
                deleteConfirmedPerformed(target);
            }
        });

        initSearch();
        initTable(mainForm);

        mainForm.add(new ExecuteChangeOptionsPanel(ID_EXECUTE_OPTIONS, executeOptionsModel, false));
    }

    private IModel<String> createDeleteConfirmString() {
        return new AbstractReadOnlyModel<String>() {

            @Override
            public String getObject() {
                if (singleDelete == null) {
                    return createStringResource("pageUsers.message.deleteUserConfirm",
                            WebMiscUtil.getSelectedData(getTable()).size()).getString();
                } else {
                    return createStringResource("pageUsers.message.deleteUserConfirmSingle", singleDelete.getName())
                            .getString();
                }
            }
        };
    }

    private List<IColumn<UserListItemDto, String>> initColumns() {
        List<IColumn<UserListItemDto, String>> columns = new ArrayList<IColumn<UserListItemDto, String>>();

        columns.add(new CheckBoxHeaderColumn());
        columns.add(new IconColumn<UserListItemDto>(null) {

            @Override
            protected IModel<String> createIconModel(final IModel<UserListItemDto> rowModel) {
                return new AbstractReadOnlyModel<String>() {

                    @Override
                    public String getObject() {
                        return rowModel.getObject().getIcon();
                    }
                };
            }

            @Override
            protected IModel<String> createTitleModel(final IModel<UserListItemDto> rowModel) {
                return new AbstractReadOnlyModel<String>() {

                    @Override
                    public String getObject() {
                        String key = rowModel.getObject().getIconTitle();
                        if (key == null) {
                            return null;
                        }
                        return createStringResource(key).getString();
                    }
                };
            }
        });

        IColumn column = new LinkColumn<UserListItemDto>(createStringResource("ObjectType.name"),
                UserType.F_NAME.getLocalPart(), UserListItemDto.F_NAME) {

            @Override
            public void onClick(AjaxRequestTarget target, IModel<UserListItemDto> rowModel) {
                userDetailsPerformed(target, rowModel.getObject().getOid());
            }
        };
        columns.add(column);

        column = new PropertyColumn(createStringResource("UserType.givenName"),
                UserType.F_GIVEN_NAME.getLocalPart(), UserListItemDto.F_GIVEN_NAME);
        columns.add(column);

        column = new PropertyColumn(createStringResource("UserType.familyName"),
                UserType.F_FAMILY_NAME.getLocalPart(), UserListItemDto.F_FAMILY_NAME);
        columns.add(column);

        column = new PropertyColumn(createStringResource("UserType.fullName"), UserType.F_FULL_NAME.getLocalPart(),
                UserListItemDto.F_FULL_NAME);
        columns.add(column);

        column = new PropertyColumn(createStringResource("UserType.emailAddress"), null, UserListItemDto.F_EMAIL);
        columns.add(column);

        column = new PropertyColumn(createStringResource("pageUsers.accounts"), null,
                UserListItemDto.F_ACCOUNT_COUNT);
        columns.add(column);

        column = new InlineMenuHeaderColumn(initInlineMenu());
        columns.add(column);

        return columns;
    }

    private List<InlineMenuItem> initInlineMenu() {
        List<InlineMenuItem> headerMenuItems = new ArrayList<InlineMenuItem>();
        headerMenuItems.add(
                new InlineMenuItem(createStringResource("pageUsers.menu.enable"), true, new HeaderMenuAction(this) {

                    @Override
                    public void onSubmit(AjaxRequestTarget target, Form<?> form) {
                        updateActivationPerformed(target, true, null);
                    }
                }));

        headerMenuItems.add(new InlineMenuItem(createStringResource("pageUsers.menu.disable"), true,
                new HeaderMenuAction(this) {

                    @Override
                    public void onSubmit(AjaxRequestTarget target, Form<?> form) {
                        updateActivationPerformed(target, false, null);
                    }
                }));

        headerMenuItems.add(new InlineMenuItem(createStringResource("pageUsers.menu.reconcile"), true,
                new HeaderMenuAction(this) {

                    @Override
                    public void onSubmit(AjaxRequestTarget target, Form<?> form) {
                        reconcilePerformed(target, null);
                    }
                }));

        headerMenuItems.add(new InlineMenuItem());

        headerMenuItems.add(
                new InlineMenuItem(createStringResource("pageUsers.menu.delete"), true, new HeaderMenuAction(this) {

                    @Override
                    public void onSubmit(AjaxRequestTarget target, Form<?> form) {
                        deletePerformed(target, null);
                    }
                }));

        return headerMenuItems;
    }

    private void initTable(Form mainForm) {
        List<IColumn<UserListItemDto, String>> columns = initColumns();

        ObjectDataProvider<UserListItemDto, UserType> provider = new ObjectDataProvider<UserListItemDto, UserType>(
                PageUsers.this, UserType.class) {

            @Override
            protected void saveProviderPaging(ObjectQuery query, ObjectPaging paging) {
                UsersStorage storage = getSessionStorage().getUsers();
                storage.setUsersPaging(paging);
            }

            @Override
            public UserListItemDto createDataObjectWrapper(PrismObject<UserType> obj) {
                return createRowDto(obj);
            }
        };
        provider.setQuery(createQuery());

        Collection<SelectorOptions<GetOperationOptions>> options = new ArrayList<SelectorOptions<GetOperationOptions>>();
        options.add(SelectorOptions.create(UserType.F_LINK_REF,
                GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE)));
        options.add(SelectorOptions.create(UserType.F_ASSIGNMENT,
                GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE)));
        provider.setOptions(options);

        TablePanel table = new TablePanel(ID_TABLE, provider, columns);
        table.setOutputMarkupId(true);

        UsersStorage storage = getSessionStorage().getUsers();
        table.setCurrentPage(storage.getUsersPaging());

        mainForm.add(table);
    }

    private UserListItemDto createRowDto(PrismObject<UserType> obj) {
        UserType user = obj.asObjectable();

        UserListItemDto dto = new UserListItemDto(user.getOid(), WebMiscUtil.getOrigStringFromPoly(user.getName()),
                WebMiscUtil.getOrigStringFromPoly(user.getGivenName()),
                WebMiscUtil.getOrigStringFromPoly(user.getFamilyName()),
                WebMiscUtil.getOrigStringFromPoly(user.getFullName()), user.getEmailAddress());

        dto.setAccountCount(createAccountCount(obj));
        dto.setCredentials(obj.findContainer(UserType.F_CREDENTIALS));
        dto.setIcon(WebMiscUtil.createUserIcon(obj));
        dto.setIconTitle(WebMiscUtil.createUserIconTitle(obj));

        dto.getMenuItems().add(new InlineMenuItem(createStringResource("pageUsers.menu.enable"),
                new ColumnMenuAction<UserListItemDto>() {

                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        UserListItemDto rowDto = getRowModel().getObject();
                        updateActivationPerformed(target, true, rowDto);
                    }
                }));

        dto.getMenuItems().add(new InlineMenuItem(createStringResource("pageUsers.menu.disable"),
                new ColumnMenuAction<UserListItemDto>() {

                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        UserListItemDto rowDto = getRowModel().getObject();
                        updateActivationPerformed(target, false, rowDto);
                    }
                }));

        dto.getMenuItems().add(new InlineMenuItem(createStringResource("pageUsers.menu.reconcile"),
                new ColumnMenuAction<UserListItemDto>() {

                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        UserListItemDto rowDto = getRowModel().getObject();
                        reconcilePerformed(target, rowDto);
                    }
                }));

        dto.getMenuItems().add(new InlineMenuItem());

        dto.getMenuItems().add(new InlineMenuItem(createStringResource("pageUsers.menu.delete"),
                new ColumnMenuAction<UserListItemDto>() {

                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        UserListItemDto rowDto = getRowModel().getObject();
                        deletePerformed(target, rowDto);
                    }
                }));

        return dto;
    }

    private int createAccountCount(PrismObject<UserType> object) {
        PrismReference accountRef = object.findReference(UserType.F_LINK_REF);
        return accountRef != null ? accountRef.size() : 0;
    }

    private void initSearch() {
        final Form searchForm = new Form(ID_SEARCH_FORM);
        add(searchForm);
        searchForm.setOutputMarkupId(true);

        IModel<Map<String, String>> options = new Model(null);
        DropDownMultiChoice searchType = new DropDownMultiChoice<UsersDto.SearchType>(ID_SEARCH_TYPE,
                new PropertyModel<List<UsersDto.SearchType>>(model, UsersDto.F_TYPE),
                WebMiscUtil.createReadonlyModelFromEnum(UsersDto.SearchType.class),
                new IChoiceRenderer<UsersDto.SearchType>() {

                    @Override
                    public Object getDisplayValue(UsersDto.SearchType object) {
                        return WebMiscUtil.createLocalizedModelForEnum(object, PageUsers.this).getObject();
                    }

                    @Override
                    public String getIdValue(UsersDto.SearchType object, int index) {
                        return Integer.toString(index);
                    }
                }, options);
        searchForm.add(searchType);

        BasicSearchPanel<UsersDto> basicSearch = new BasicSearchPanel<UsersDto>(ID_BASIC_SEARCH, model) {

            @Override
            protected IModel<String> createSearchTextModel() {
                return new PropertyModel<String>(model, UsersDto.F_TEXT);
            }

            @Override
            protected void searchPerformed(AjaxRequestTarget target) {
                PageUsers.this.searchPerformed(target);
            }

            @Override
            protected void clearSearchPerformed(AjaxRequestTarget target) {
                PageUsers.this.clearSearchPerformed(target);
            }
        };
        searchForm.add(basicSearch);
    }

    private void userDetailsPerformed(AjaxRequestTarget target, String oid) {
        PageParameters parameters = new PageParameters();
        parameters.add(OnePageParameterEncoder.PARAMETER, oid);
        setResponsePage(PageUser.class, parameters);
    }

    private TablePanel getTable() {
        return (TablePanel) get(createComponentPath(ID_MAIN_FORM, ID_TABLE));
    }

    private void searchPerformed(AjaxRequestTarget target) {
        ObjectQuery query = createQuery();
        target.add(getFeedbackPanel());

        TablePanel panel = getTable();
        DataTable table = panel.getDataTable();
        ObjectDataProvider provider = (ObjectDataProvider) table.getDataProvider();
        provider.setQuery(query);

        UsersStorage storage = getSessionStorage().getUsers();
        storage.setUsersSearch(model.getObject());
        storage.setUsersPaging(null);
        panel.setCurrentPage(null);

        target.add(panel);
    }

    private ObjectQuery createQuery() {
        UsersDto dto = model.getObject();
        ObjectQuery query = null;
        if (StringUtils.isEmpty(dto.getText())) {
            return null;
        }

        try {
            List<ObjectFilter> filters = new ArrayList<ObjectFilter>();

            PolyStringNormalizer normalizer = getPrismContext().getDefaultPolyStringNormalizer();
            String normalizedString = normalizer.normalize(dto.getText());

            if (dto.hasType(UsersDto.SearchType.NAME)) {
                filters.add(SubstringFilter.createSubstring(UserType.F_NAME, UserType.class, getPrismContext(),
                        PolyStringNormMatchingRule.NAME, normalizedString));
            }

            if (dto.hasType(UsersDto.SearchType.FAMILY_NAME)) {
                filters.add(SubstringFilter.createSubstring(UserType.F_FAMILY_NAME, UserType.class,
                        getPrismContext(), PolyStringNormMatchingRule.NAME, normalizedString));
            }
            if (dto.hasType(UsersDto.SearchType.FULL_NAME)) {
                filters.add(SubstringFilter.createSubstring(UserType.F_FULL_NAME, UserType.class, getPrismContext(),
                        PolyStringNormMatchingRule.NAME, normalizedString));
            }
            if (dto.hasType(UsersDto.SearchType.GIVEN_NAME)) {
                filters.add(SubstringFilter.createSubstring(UserType.F_GIVEN_NAME, UserType.class,
                        getPrismContext(), PolyStringNormMatchingRule.NAME, normalizedString));
            }

            if (filters.size() == 1) {
                query = ObjectQuery.createObjectQuery(filters.get(0));
            } else if (filters.size() > 1) {
                query = ObjectQuery.createObjectQuery(OrFilter.createOr(filters));
            }
        } catch (Exception ex) {
            error(getString("pageUsers.message.queryError") + " " + ex.getMessage());
            LoggingUtils.logException(LOGGER, "Couldn't create query filter.", ex);
        }

        return query;
    }

    private void deletePerformed(AjaxRequestTarget target, UserListItemDto selectedUser) {
        singleDelete = selectedUser;
        List<UserListItemDto> users = isAnythingSelected(target, selectedUser);
        if (users.isEmpty()) {
            return;
        }

        ModalWindow dialog = (ModalWindow) get(DIALOG_CONFIRM_DELETE);
        dialog.show(target);
    }

    private void deleteConfirmedPerformed(AjaxRequestTarget target) {
        List<UserListItemDto> users = new ArrayList<UserListItemDto>();

        if (singleDelete == null) {
            users = isAnythingSelected(target, null);
        } else {
            users.add(singleDelete);
        }

        if (users.isEmpty()) {
            return;
        }

        OperationResult result = new OperationResult(OPERATION_DELETE_USERS);
        for (UserListItemDto user : users) {
            OperationResult subResult = result.createSubresult(OPERATION_DELETE_USER);
            try {
                Task task = createSimpleTask(OPERATION_DELETE_USER);

                ObjectDelta delta = new ObjectDelta(UserType.class, ChangeType.DELETE, getPrismContext());
                delta.setOid(user.getOid());

                ExecuteChangeOptionsDto executeOptions = executeOptionsModel.getObject();
                ModelExecuteOptions options = executeOptions.createOptions();
                LOGGER.debug("Using options {}.", new Object[] { executeOptions });
                getModelService().executeChanges(WebMiscUtil.createDeltaCollection(delta), options, task,
                        subResult);
                subResult.computeStatus();
            } catch (Exception ex) {
                subResult.recomputeStatus();
                subResult.recordFatalError("Couldn't delete user.", ex);
                LoggingUtils.logException(LOGGER, "Couldn't delete user", ex);
            }
        }
        result.computeStatusComposite();

        ObjectDataProvider<UserListItemDto, UserType> provider = (ObjectDataProvider) getTable().getDataTable()
                .getDataProvider();
        provider.clearCache();

        showResult(result);
        target.add(getFeedbackPanel());
        target.add(getTable());
    }

    public static String toShortString(UserListItemDto object) {
        if (object == null) {
            return "null";
        }
        StringBuilder builder = new StringBuilder();
        builder.append(ObjectTypeUtil.getShortTypeName(UserType.class));
        builder.append(": ");
        builder.append(object.getName());
        builder.append(" (OID:");
        builder.append(object.getOid());
        builder.append(")");

        return builder.toString();
    }

    private void reconcilePerformed(AjaxRequestTarget target, UserListItemDto selectedUser) {
        List<UserListItemDto> users = isAnythingSelected(target, selectedUser);
        if (users.isEmpty()) {
            return;
        }

        OperationResult result = new OperationResult(OPERATION_RECONCILE_USERS);
        for (UserListItemDto user : users) {
            String userShortString = toShortString(user);
            OperationResult opResult = result.createSubresult(getString(OPERATION_RECONCILE_USER, userShortString));
            try {
                Task task = createSimpleTask(OPERATION_RECONCILE_USER + userShortString);
                ObjectDelta delta = ObjectDelta.createEmptyModifyDelta(UserType.class, user.getOid(),
                        getPrismContext());
                Collection<ObjectDelta<? extends ObjectType>> deltas = WebMiscUtil.createDeltaCollection(delta);
                getModelService().executeChanges(deltas, ModelExecuteOptions.createReconcile(), task, opResult);
                opResult.recordSuccess();
            } catch (Exception ex) {
                opResult.recomputeStatus();
                opResult.recordFatalError("Couldn't reconcile user " + userShortString + ".", ex);
                LoggingUtils.logException(LOGGER, "Couldn't reconcile user " + userShortString + ".", ex);
            }
        }

        result.recomputeStatus();

        showResult(result);
        target.add(getFeedbackPanel());
        target.add(getTable());
    }

    /**
     * This method check selection in table. If selectedUser != null than it returns only this user.
     */
    private List<UserListItemDto> isAnythingSelected(AjaxRequestTarget target, UserListItemDto selectedUser) {
        List<UserListItemDto> users;
        if (selectedUser != null) {
            users = new ArrayList<UserListItemDto>();
            users.add(selectedUser);
        } else {
            users = WebMiscUtil.getSelectedData(getTable());
            if (users.isEmpty()) {
                warn(getString("pageUsers.message.nothingSelected"));
                target.add(getFeedbackPanel());
            }
        }

        return users;
    }

    /**
     * This method updates user activation. If userOid parameter is not null, than it updates only that user,
     * otherwise it checks table for selected users.
     */
    private void updateActivationPerformed(AjaxRequestTarget target, boolean enabling,
            UserListItemDto selectedUser) {
        List<UserListItemDto> users = isAnythingSelected(target, selectedUser);
        if (users.isEmpty()) {
            return;
        }

        String operation = enabling ? OPERATION_ENABLE_USERS : OPERATION_DISABLE_USERS;
        OperationResult result = new OperationResult(operation);
        for (UserListItemDto user : users) {
            operation = enabling ? OPERATION_ENABLE_USER : OPERATION_DISABLE_USER;
            OperationResult subResult = result.createSubresult(operation);
            try {
                Task task = createSimpleTask(operation);

                ObjectDelta objectDelta = WebModelUtils.createActivationAdminStatusDelta(UserType.class,
                        user.getOid(), enabling, getPrismContext());

                ExecuteChangeOptionsDto executeOptions = executeOptionsModel.getObject();
                ModelExecuteOptions options = executeOptions.createOptions();
                LOGGER.debug("Using options {}.", new Object[] { executeOptions });
                getModelService().executeChanges(WebMiscUtil.createDeltaCollection(objectDelta), options, task,
                        subResult);
                subResult.recordSuccess();
            } catch (Exception ex) {
                subResult.recomputeStatus();
                if (enabling) {
                    subResult.recordFatalError("Couldn't enable user.", ex);
                    LoggingUtils.logException(LOGGER, "Couldn't enable user", ex);
                } else {
                    subResult.recordFatalError("Couldn't disable user.", ex);
                    LoggingUtils.logException(LOGGER, "Couldn't disable user", ex);
                }
            }
        }
        result.recomputeStatus();

        showResult(result);
        target.add(getFeedbackPanel());
        target.add(getTable());
    }

    private void clearSearchPerformed(AjaxRequestTarget target) {
        model.setObject(new UsersDto());

        TablePanel panel = getTable();
        DataTable table = panel.getDataTable();
        ObjectDataProvider provider = (ObjectDataProvider) table.getDataProvider();
        provider.setQuery(null);

        UsersStorage storage = getSessionStorage().getUsers();
        storage.setUsersSearch(model.getObject());
        storage.setUsersPaging(null);
        panel.setCurrentPage(null);

        target.add(get(ID_SEARCH_FORM));
        target.add(panel);
    }
}