com.evolveum.midpoint.gui.impl.component.MultivalueContainerListPanel.java Source code

Java tutorial

Introduction

Here is the source code for com.evolveum.midpoint.gui.impl.component.MultivalueContainerListPanel.java

Source

/*
 * Copyright (c) 2018 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.gui.impl.component;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.evolveum.midpoint.web.component.menu.cog.ButtonInlineMenuItem;
import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItemAction;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;

import com.evolveum.midpoint.gui.api.GuiStyleConstants;
import com.evolveum.midpoint.gui.api.component.BasePanel;
import com.evolveum.midpoint.gui.api.model.LoadableModel;
import com.evolveum.midpoint.gui.impl.util.GuiImplUtil;
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.PrismContainerDefinition;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.query.ObjectPaging;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.component.AjaxIconButton;
import com.evolveum.midpoint.web.component.data.BoxedTablePanel;
import com.evolveum.midpoint.web.component.data.Table;
import com.evolveum.midpoint.web.component.data.column.ColumnMenuAction;
import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItem;
import com.evolveum.midpoint.web.component.objectdetails.FocusMainPanel;
import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper;
import com.evolveum.midpoint.web.component.prism.ContainerWrapper;
import com.evolveum.midpoint.web.component.prism.ContainerWrapperFactory;
import com.evolveum.midpoint.web.component.prism.ValueStatus;
import com.evolveum.midpoint.web.component.search.Search;
import com.evolveum.midpoint.web.component.search.SearchFormPanel;
import com.evolveum.midpoint.web.component.search.SearchItemDefinition;
import com.evolveum.midpoint.web.component.util.MultivalueContainerListDataProvider;
import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour;
import com.evolveum.midpoint.web.session.PageStorage;
import com.evolveum.midpoint.web.session.UserProfileStorage.TableId;

/**
 * @author skublik
 */

public abstract class MultivalueContainerListPanel<C extends Containerable> extends BasePanel<ContainerWrapper<C>> {

    private static final long serialVersionUID = 1L;

    public static final String ID_ITEMS = "items";
    private static final String ID_ITEMS_TABLE = "itemsTable";
    public static final String ID_SEARCH_ITEM_PANEL = "search";

    public static final String ID_DETAILS = "details";

    private static final Trace LOGGER = TraceManager.getTrace(MultivalueContainerListPanel.class);

    private TableId tableId;
    private PageStorage pageStorage;

    private LoadableModel<Search> searchModel = null;

    public MultivalueContainerListPanel(String id, IModel<ContainerWrapper<C>> model, TableId tableId,
            PageStorage pageStorage) {
        super(id, model);
        this.tableId = tableId;
        this.pageStorage = pageStorage;

        searchModel = new LoadableModel<Search>(false) {

            private static final long serialVersionUID = 1L;

            @Override
            protected Search load() {
                PrismContainerDefinition<C> containerDef = model.getObject().getItemDefinition();
                List<SearchItemDefinition> availableDefs = initSearchableItems(containerDef);

                Search search = new Search(model.getObject().getItem().getCompileTimeClass(), availableDefs);
                return search;
            }

        };
    }

    protected abstract List<SearchItemDefinition> initSearchableItems(PrismContainerDefinition<C> containerDef);

    @Override
    protected void onInitialize() {
        super.onInitialize();

        initPaging();
        initLayout();
    }

    private void initLayout() {

        initListPanel();

        initCustomLayout();

        setOutputMarkupId(true);

    }

    protected abstract void initPaging();

    protected abstract void initCustomLayout();

    private void initListPanel() {
        WebMarkupContainer itemsContainer = new WebMarkupContainer(ID_ITEMS);
        itemsContainer.setOutputMarkupId(true);
        add(itemsContainer);

        BoxedTablePanel<ContainerValueWrapper<C>> itemTable = initItemTable();
        itemsContainer.add(itemTable);

        WebMarkupContainer searchContainer = getSearchPanel(ID_SEARCH_ITEM_PANEL);
        itemsContainer.add(searchContainer);
        itemsContainer.add(new VisibleEnableBehaviour() {

            private static final long serialVersionUID = 1L;

            @Override
            public boolean isVisible() {
                return isListPanelVisible();
            }
        });

    }

    protected boolean isListPanelVisible() {
        return true;
    }

    protected WebMarkupContainer getSearchPanel(String contentAreaId) {
        return new WebMarkupContainer(contentAreaId);
    }

    protected abstract boolean enableActionNewObject();

    private BoxedTablePanel<ContainerValueWrapper<C>> initItemTable() {

        MultivalueContainerListDataProvider<C> containersProvider = new MultivalueContainerListDataProvider<C>(this,
                new PropertyModel<>(getModel(), "values")) {
            private static final long serialVersionUID = 1L;

            @Override
            protected void saveProviderPaging(ObjectQuery query, ObjectPaging paging) {
                pageStorage.setPaging(paging);
            }

            @Override
            public ObjectQuery getQuery() {
                return MultivalueContainerListPanel.this.createProviderQuery();
            }

            @Override
            protected List<ContainerValueWrapper<C>> searchThroughList() {
                List<ContainerValueWrapper<C>> resultList = super.searchThroughList();
                return postSearch(resultList);
            }

        };

        List<IColumn<ContainerValueWrapper<C>, String>> columns = createColumns();

        int itemPerPage = (int) getPageBase().getItemsPerPage(tableId);
        BoxedTablePanel<ContainerValueWrapper<C>> itemTable = new BoxedTablePanel<ContainerValueWrapper<C>>(
                ID_ITEMS_TABLE, containersProvider, columns, tableId, itemPerPage) {
            private static final long serialVersionUID = 1L;

            @Override
            protected WebMarkupContainer createHeader(String headerId) {
                return MultivalueContainerListPanel.this.initSearch(headerId);
            }

            @Override
            public int getItemsPerPage() {
                return getPageBase().getSessionStorage().getUserProfile().getTables().get(getTableId());
            }

            @Override
            protected Item<ContainerValueWrapper<C>> customizeNewRowItem(Item<ContainerValueWrapper<C>> item,
                    IModel<ContainerValueWrapper<C>> model) {
                item.add(AttributeModifier.append("class", new IModel<String>() {

                    private static final long serialVersionUID = 1L;

                    @Override
                    public String getObject() {
                        return GuiImplUtil
                                .getObjectStatus(((ContainerValueWrapper<Containerable>) model.getObject()));
                    }
                }));
                return item;
            }

            @Override
            protected WebMarkupContainer createButtonToolbar(String id) {
                return initButtonToolbar(id);
            }

        };
        itemTable.setOutputMarkupId(true);
        itemTable.setCurrentPage(pageStorage.getPaging());
        return itemTable;

    }

    protected WebMarkupContainer initButtonToolbar(String id) {
        return getNewItemButton(id);
    }

    public AjaxIconButton getNewItemButton(String id) {
        AjaxIconButton newObjectIcon = new AjaxIconButton(id, new Model<>("fa fa-plus"),
                getNewObjectButtonTitleModel()) {

            private static final long serialVersionUID = 1L;

            @Override
            public void onClick(AjaxRequestTarget target) {
                newItemPerformed(target);
            }
        };

        newObjectIcon.add(new VisibleEnableBehaviour() {
            private static final long serialVersionUID = 1L;

            @Override
            public boolean isVisible() {
                return enableActionNewObject();
            }

            @Override
            public boolean isEnabled() {
                return isNewObjectButtonEnabled();
            }
        });
        newObjectIcon.add(AttributeModifier.append("class", createStyleClassModelForNewObjectIcon()));
        return newObjectIcon;
    }

    protected boolean isNewObjectButtonEnabled() {
        return true;
    }

    protected IModel<String> getNewObjectButtonTitleModel() {
        return createStringResource("MainObjectListPanel.newObject");
    }

    protected WebMarkupContainer initSearch(String headerId) {
        SearchFormPanel searchPanel = new SearchFormPanel(headerId, searchModel) {

            private static final long serialVersionUID = 1L;

            @Override
            protected void searchPerformed(ObjectQuery query, AjaxRequestTarget target) {
                MultivalueContainerListPanel.this.searchPerformed(query, target);
            }
        };
        return searchPanel;
    }

    private void searchPerformed(ObjectQuery query, AjaxRequestTarget target) {

        //      MultivalueContainerListDataProvider<C> provider = getDataProvider();

        //      ObjectQuery finalQuery = null;
        //
        //      ObjectQuery searchQuery = getQuery();
        //
        //      ObjectQuery customQuery = createQuery();
        //
        //      if (query != null && query.getFilter() != null) {
        //         if (customQuery != null && customQuery.getFilter() != null) {
        //            finalQuery = ObjectQuery.createObjectQuery(AndFilter.createAnd(customQuery.getFilter(), query.getFilter()));
        //         }
        //         finalQuery = query;
        //
        //      } else {
        //         finalQuery = customQuery;
        //      }
        //
        //      provider.setQuery(finalQuery);
        //      String storageKey = getStorageKey();
        //      if (StringUtils.isNotEmpty(storageKey)) {
        //         PageStorage storage = getPageStorage(storageKey);
        //         if (storage != null) {
        //            storage.setSearch(searchModel.getObject());
        //            storage.setPaging(null);
        //         }
        //      }
        //      
        Table table = getItemTable();
        table.setCurrentPage(null);
        target.add((Component) table);
        target.add(getPageBase().getFeedbackPanel());

    }

    private ObjectQuery getQuery() {
        Search search = searchModel.getObject();
        ObjectQuery query = search.createObjectQuery(getPageBase().getPrismContext());
        //      query = addFilterToContentQuery(query);
        return query;
    }

    private MultivalueContainerListDataProvider<C> getDataProvider() {
        return (MultivalueContainerListDataProvider<C>) getItemTable().getDataTable().getDataProvider();
    }

    protected IModel<String> createStyleClassModelForNewObjectIcon() {
        return new IModel<String>() {
            private static final long serialVersionUID = 1L;

            @Override
            public String getObject() {
                return "btn btn-success btn-sm";
            }
        };
    }

    protected abstract List<ContainerValueWrapper<C>> postSearch(List<ContainerValueWrapper<C>> items);

    private ObjectQuery createProviderQuery() {
        ObjectQuery searchQuery = getQuery();

        ObjectQuery customQuery = createQuery();

        if (searchQuery != null && searchQuery.getFilter() != null) {
            if (customQuery != null && customQuery.getFilter() != null) {
                return getPrismContext().queryFactory().createQuery(getPrismContext().queryFactory()
                        .createAnd(customQuery.getFilter(), searchQuery.getFilter()));
            }
            return searchQuery;

        }
        return customQuery;
    }

    protected abstract ObjectQuery createQuery();

    protected abstract List<IColumn<ContainerValueWrapper<C>, String>> createColumns();

    protected abstract void newItemPerformed(AjaxRequestTarget target);

    public BoxedTablePanel<ContainerValueWrapper<C>> getItemTable() {
        return (BoxedTablePanel<ContainerValueWrapper<C>>) get(createComponentPath(ID_ITEMS, ID_ITEMS_TABLE));
    }

    public void refreshTable(AjaxRequestTarget ajaxRequestTarget) {
        ajaxRequestTarget.add(getItemContainer().addOrReplace(initItemTable()));
    }

    public WebMarkupContainer getItemContainer() {
        return (WebMarkupContainer) get(ID_ITEMS);
    }

    public PrismObject getFocusObject() {
        FocusMainPanel mainPanel = findParent(FocusMainPanel.class);
        if (mainPanel != null) {
            return mainPanel.getObjectWrapper().getObject();
        }
        return null;
    }

    public List<ContainerValueWrapper<C>> getSelectedItems() {
        BoxedTablePanel<ContainerValueWrapper<C>> itemsTable = getItemTable();
        MultivalueContainerListDataProvider<C> itemsProvider = (MultivalueContainerListDataProvider<C>) itemsTable
                .getDataTable().getDataProvider();
        return itemsProvider.getAvailableData().stream().filter(a -> a.isSelected()).collect(Collectors.toList());
    }

    public void reloadSavePreviewButtons(AjaxRequestTarget target) {
        FocusMainPanel mainPanel = findParent(FocusMainPanel.class);
        if (mainPanel != null) {
            mainPanel.reloadSavePreviewButtons(target);
        }
    }

    public ContainerValueWrapper<C> createNewItemContainerValueWrapper(PrismContainerValue<C> newItem,
            IModel<ContainerWrapper<C>> model) {
        ContainerWrapperFactory factory = new ContainerWrapperFactory(getPageBase());
        Task task = getPageBase().createSimpleTask("Creating new object policy");
        ContainerValueWrapper<C> valueWrapper = factory.createContainerValueWrapper(model.getObject(), newItem,
                model.getObject().getObjectStatus(), ValueStatus.ADDED, model.getObject().getPath(), task);
        valueWrapper.setShowEmpty(true, true);
        model.getObject().getValues().add(valueWrapper);
        return valueWrapper;
    }

    public ColumnMenuAction<ContainerValueWrapper<C>> createDeleteColumnAction() {
        return new ColumnMenuAction<ContainerValueWrapper<C>>() {
            private static final long serialVersionUID = 1L;

            @Override
            public void onClick(AjaxRequestTarget target) {
                if (getRowModel() == null) {
                    deleteItemPerformed(target, getSelectedItems());
                } else {
                    List<ContainerValueWrapper<C>> toDelete = new ArrayList<>();
                    toDelete.add(getRowModel().getObject());
                    deleteItemPerformed(target, toDelete);
                }
            }
        };
    }

    public ColumnMenuAction<ContainerValueWrapper<C>> createEditColumnAction() {
        return new ColumnMenuAction<ContainerValueWrapper<C>>() {
            private static final long serialVersionUID = 1L;

            @Override
            public void onClick(AjaxRequestTarget target) {
                itemPerformedForDefaultAction(target, getRowModel(), getSelectedItems());
            }
        };
    }

    protected abstract void itemPerformedForDefaultAction(AjaxRequestTarget target,
            IModel<ContainerValueWrapper<C>> rowModel, List<ContainerValueWrapper<C>> listItems);

    protected void deleteItemPerformed(AjaxRequestTarget target, List<ContainerValueWrapper<C>> toDelete) {
        if (toDelete == null || toDelete.isEmpty()) {
            warn(createStringResource("MultivalueContainerListPanel.message.noAssignmentSelected").getString());
            target.add(getPageBase().getFeedbackPanel());
            return;
        }
        toDelete.forEach(value -> {
            if (value.getStatus() == ValueStatus.ADDED) {
                ContainerWrapper<C> wrapper = getModelObject();
                wrapper.getValues().remove(value);
            } else {
                value.setStatus(ValueStatus.DELETED);
            }
            value.setSelected(false);
        });
        refreshTable(target);
        reloadSavePreviewButtons(target);
    }

    public List<InlineMenuItem> getDefaultMenuActions() {
        List<InlineMenuItem> menuItems = new ArrayList<>();
        menuItems.add(new ButtonInlineMenuItem(createStringResource("PageBase.button.unassign")) {
            private static final long serialVersionUID = 1L;

            @Override
            public String getButtonIconCssClass() {
                return GuiStyleConstants.CLASS_DELETE_MENU_ITEM;
            }

            @Override
            public InlineMenuItemAction initAction() {
                return createDeleteColumnAction();
            }
        });

        menuItems.add(new ButtonInlineMenuItem(createStringResource("PageBase.button.edit")) {
            private static final long serialVersionUID = 1L;

            @Override
            public String getButtonIconCssClass() {
                return GuiStyleConstants.CLASS_EDIT_MENU_ITEM;
            }

            @Override
            public InlineMenuItemAction initAction() {
                return createEditColumnAction();
            }
        });
        return menuItems;
    }
}