com.evolveum.midpoint.web.component.util.FocusListInlineMenuHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.evolveum.midpoint.web.component.util.FocusListInlineMenuHelper.java

Source

/*
 * Copyright (c) 2010-2016 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.component.util;

import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils;
import com.evolveum.midpoint.model.api.ModelExecuteOptions;
import com.evolveum.midpoint.prism.delta.ChangeType;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.CommonException;
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.component.data.column.ColumnMenuAction;
import com.evolveum.midpoint.web.component.dialog.ConfirmationPanel;
import com.evolveum.midpoint.web.component.dialog.Popupable;
import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItem;
import com.evolveum.midpoint.web.page.admin.configuration.component.HeaderMenuAction;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.jetbrains.annotations.NotNull;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Provides common inline menu functionality for focal objects: enable, disable, reconcile, delete.
 *
 * TODO deduplicate this functionality with the one in PageUsers
 *
 * @author mederly
 */
public class FocusListInlineMenuHelper<F extends FocusType> implements Serializable {

    private static final long serialVersionUID = 1L;

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

    // these are prefixed by parent page class name
    private static final String OPERATION_ENABLE_OBJECTS = "enableObjects";
    private static final String OPERATION_DISABLE_OBJECTS = "disableObjects";
    private static final String OPERATION_ENABLE_OBJECT = "enableObject";
    private static final String OPERATION_DISABLE_OBJECT = "disableObject";
    private static final String OPERATION_RECONCILE_OBJECTS = "reconcileObjects";
    private static final String OPERATION_RECONCILE_OBJECT = "reconcileObject";
    private static final String OPERATION_DELETE_OBJECTS = "deleteObjects";
    private static final String OPERATION_DELETE_OBJECT = "deleteObject";

    @NotNull
    private final Class<F> objectClass;
    @NotNull
    private final PageBase parentPage;
    @NotNull
    private final FocusListComponent<F> focusListComponent;
    private F singleDelete;

    public FocusListInlineMenuHelper(@NotNull Class<F> objectClass, @NotNull PageBase parentPage,
            @NotNull FocusListComponent<F> focusListComponent) {
        this.objectClass = objectClass;
        this.parentPage = parentPage;
        this.focusListComponent = focusListComponent;
    }

    public List<InlineMenuItem> initInlineMenu() {
        List<InlineMenuItem> headerMenuItems = new ArrayList<>();
        headerMenuItems
                .add(new InlineMenuItem(parentPage.createStringResource("FocusListInlineMenuHelper.menu.enable"),
                        true, new HeaderMenuAction(parentPage) {
                            @Override
                            public void onSubmit(AjaxRequestTarget target, Form<?> form) {
                                updateActivationPerformed(target, true, null);
                            }
                        }));

        headerMenuItems
                .add(new InlineMenuItem(parentPage.createStringResource("FocusListInlineMenuHelper.menu.disable"),
                        true, new HeaderMenuAction(parentPage) {
                            @Override
                            public void onSubmit(AjaxRequestTarget target, Form<?> form) {
                                updateActivationPerformed(target, false, null);
                            }
                        }));

        headerMenuItems
                .add(new InlineMenuItem(parentPage.createStringResource("FocusListInlineMenuHelper.menu.reconcile"),
                        true, new HeaderMenuAction(parentPage) {
                            @Override
                            public void onSubmit(AjaxRequestTarget target, Form<?> form) {
                                reconcilePerformed(target, null);
                            }
                        }));

        headerMenuItems.add(new InlineMenuItem());

        headerMenuItems
                .add(new InlineMenuItem(parentPage.createStringResource("FocusListInlineMenuHelper.menu.delete"),
                        true, new HeaderMenuAction(parentPage) {

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

        return headerMenuItems;
    }

    public List<InlineMenuItem> createRowActions() {
        List<InlineMenuItem> menu = new ArrayList<>();
        menu.add(new InlineMenuItem(parentPage.createStringResource("FocusListInlineMenuHelper.menu.enable"),
                new ColumnMenuAction<SelectableBean<F>>() {

                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        SelectableBean<F> rowDto = getRowModel().getObject();
                        updateActivationPerformed(target, true, rowDto.getValue());
                    }
                }));

        menu.add(new InlineMenuItem(parentPage.createStringResource("FocusListInlineMenuHelper.menu.disable"),
                new ColumnMenuAction<SelectableBean<F>>() {

                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        SelectableBean<F> rowDto = getRowModel().getObject();
                        updateActivationPerformed(target, false, rowDto.getValue());
                    }
                }));

        menu.add(new InlineMenuItem(parentPage.createStringResource("FocusListInlineMenuHelper.menu.reconcile"),
                new ColumnMenuAction<SelectableBean<F>>() {

                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        SelectableBean<F> rowDto = getRowModel().getObject();
                        reconcilePerformed(target, rowDto.getValue());
                    }
                }));

        menu.add(new InlineMenuItem());

        menu.add(new InlineMenuItem(parentPage.createStringResource("FocusListInlineMenuHelper.menu.delete"),
                new ColumnMenuAction<SelectableBean<F>>() {

                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        SelectableBean<F> rowDto = getRowModel().getObject();
                        deletePerformed(target, rowDto.getValue());
                    }
                }));
        return menu;
    }

    private IModel<String> createDeleteConfirmString() {
        return new AbstractReadOnlyModel<String>() {
            @Override
            public String getObject() {
                if (singleDelete == null) {
                    return parentPage
                            .createStringResource("FocusListInlineMenuHelper.message.deleteObjectConfirm",
                                    focusListComponent.getObjectListPanel().getSelectedObjects().size())
                            .getString();
                } else {
                    return parentPage
                            .createStringResource("FocusListInlineMenuHelper.message.deleteObjectConfirmSingle",
                                    singleDelete.getName())
                            .getString();
                }
            }
        };
    }

    public Popupable getDeletePopupContent() {
        return new ConfirmationPanel(parentPage.getMainPopupBodyId(), createDeleteConfirmString()) {
            @Override
            public void yesPerformed(AjaxRequestTarget target) {
                parentPage.hideMainPopup(target);
                deleteConfirmedPerformed(target);
            }
        };
    }

    private void deletePerformed(AjaxRequestTarget target, F selectedObject) {
        singleDelete = selectedObject;
        List<F> objects = getObjectsToActOn(target, selectedObject);
        if (objects.isEmpty()) {
            return;
        }
        parentPage.showMainPopup(getDeletePopupContent(), target);
    }

    public void deleteConfirmedPerformed(AjaxRequestTarget target) {
        List<F> objects = getObjectsToActOn(target, singleDelete);
        if (objects.isEmpty()) {
            return;
        }

        OperationResult result = new OperationResult(getOperationName(OPERATION_DELETE_OBJECTS));
        for (F object : objects) {
            OperationResult subResult = result.createSubresult(getOperationName(OPERATION_DELETE_OBJECT));
            try {
                Task task = parentPage.createSimpleTask(getOperationName(OPERATION_DELETE_OBJECT));

                ObjectDelta delta = new ObjectDelta(objectClass, ChangeType.DELETE, parentPage.getPrismContext());
                delta.setOid(object.getOid());
                parentPage.getModelService().executeChanges(WebComponentUtil.createDeltaCollection(delta), null,
                        task, subResult);
                subResult.computeStatus();
            } catch (CommonException | RuntimeException ex) {
                subResult.recomputeStatus();
                subResult.recordFatalError("Couldn't delete object.", ex);
                LoggingUtils.logUnexpectedException(LOGGER, "Couldn't delete object", ex);
            }
        }
        result.computeStatusComposite();
        focusListComponent.getObjectListPanel().clearCache();

        parentPage.showResult(result);
        target.add(parentPage.getFeedbackPanel());
        focusListComponent.getObjectListPanel().refreshTable(objectClass, target);
        focusListComponent.getObjectListPanel().clearCache();
    }

    /**
     * This method updates object activation. If selectedObject parameter is not null,
     * than it updates only that objects, otherwise it checks table for selected
     * objects.
     */
    private void updateActivationPerformed(AjaxRequestTarget target, boolean enabling, F selectedObject) {
        List<F> objects = getObjectsToActOn(target, selectedObject);
        if (objects.isEmpty()) {
            return;
        }

        OperationResult result = new OperationResult(
                getOperationName(enabling ? OPERATION_ENABLE_OBJECTS : OPERATION_DISABLE_OBJECTS));
        for (F object : objects) {
            String operationName = getOperationName(enabling ? OPERATION_ENABLE_OBJECT : OPERATION_DISABLE_OBJECT);
            OperationResult subResult = result.createSubresult(operationName);
            try {
                Task task = parentPage.createSimpleTask(operationName);

                ObjectDelta objectDelta = WebModelServiceUtils.createActivationAdminStatusDelta(objectClass,
                        object.getOid(), enabling, parentPage.getPrismContext());
                parentPage.getModelService().executeChanges(WebComponentUtil.createDeltaCollection(objectDelta),
                        null, task, subResult);
                subResult.recordSuccess();
            } catch (CommonException | RuntimeException ex) {
                subResult.recomputeStatus();
                if (enabling) {
                    subResult.recordFatalError("Couldn't enable object.", ex);
                    LoggingUtils.logUnexpectedException(LOGGER, "Couldn't enable object", ex);
                } else {
                    subResult.recordFatalError("Couldn't disable object.", ex);
                    LoggingUtils.logUnexpectedException(LOGGER, "Couldn't disable object", ex);
                }
            }
        }
        result.recomputeStatus();

        parentPage.showResult(result);
        target.add(parentPage.getFeedbackPanel());
        focusListComponent.getObjectListPanel().clearCache();
        focusListComponent.getObjectListPanel().refreshTable(objectClass, target);
    }

    private void reconcilePerformed(AjaxRequestTarget target, F selectedObject) {
        List<F> objects = getObjectsToActOn(target, selectedObject);
        if (objects.isEmpty()) {
            return;
        }

        OperationResult result = new OperationResult(getOperationName(OPERATION_RECONCILE_OBJECTS));
        for (F object : objects) {
            OperationResult opResult = result.createSubresult(getOperationName(OPERATION_RECONCILE_OBJECT));
            try {
                Task task = parentPage.createSimpleTask(OPERATION_RECONCILE_OBJECT);
                ObjectDelta delta = ObjectDelta.createEmptyModifyDelta(objectClass, object.getOid(),
                        parentPage.getPrismContext());
                Collection<ObjectDelta<? extends ObjectType>> deltas = WebComponentUtil
                        .createDeltaCollection(delta);
                parentPage.getModelService().executeChanges(deltas, ModelExecuteOptions.createReconcile(), task,
                        opResult);
                opResult.computeStatusIfUnknown();
            } catch (CommonException | RuntimeException ex) {
                opResult.recomputeStatus();
                opResult.recordFatalError("Couldn't reconcile object " + object + ".", ex);
                LoggingUtils.logUnexpectedException(LOGGER, "Couldn't reconcile object " + object + ".", ex);
            }
        }

        result.recomputeStatus();

        parentPage.showResult(result);
        target.add(parentPage.getFeedbackPanel());
        focusListComponent.getObjectListPanel().refreshTable(objectClass, target);
        focusListComponent.getObjectListPanel().clearCache();
    }

    private String getOperationName(String suffix) {
        return parentPage.getClass().getName() + "." + suffix;
    }

    /**
     * This method check selection in table. If selectedObject != null than it
     * returns only this object.
     */
    private List<F> getObjectsToActOn(AjaxRequestTarget target, F selectedObject) {
        if (selectedObject != null) {
            return Collections.singletonList(selectedObject);
        } else {
            List<F> objects;
            objects = focusListComponent.getObjectListPanel().getSelectedObjects();
            if (objects.isEmpty()) {
                parentPage.warn(parentPage.getString("FocusListInlineMenuHelper.message.nothingSelected"));
                target.add(parentPage.getFeedbackPanel());
            }
            return objects;
        }
    }

}