/* * 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.workflow; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.model.api.WorkflowService; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.security.api.MidPointPrincipal; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.CommonException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SecurityViolationException; 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.AjaxButton; import com.evolveum.midpoint.web.component.data.BoxedTablePanel; import com.evolveum.midpoint.web.component.util.Selectable; import com.evolveum.midpoint.web.page.admin.server.PageTaskEdit; import com.evolveum.midpoint.web.page.admin.workflow.dto.ProcessInstanceDto; import com.evolveum.midpoint.web.page.admin.workflow.dto.ProcessInstanceDtoProvider; import com.evolveum.midpoint.web.security.SecurityUtils; import com.evolveum.midpoint.web.session.UserProfileStorage; import com.evolveum.midpoint.web.util.OnePageParameterEncoder; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.request.mapper.parameter.PageParameters; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * @author mederly */ public abstract class PageProcessInstances extends PageAdminWorkItems { public static final String ID_BACK = "back"; public static final String ID_STOP = "stop"; public static final String ID_DELETE = "delete"; public static final String ID_PROCESS_INSTANCES_TABLE = "processInstancesTable"; public static final String ID_MAIN_FORM = "mainForm"; boolean requestedBy; // true if we want to show process instances requested BY a user boolean requestedFor; // true if we want to show instances requested FOR a user private static final Trace LOGGER = TraceManager.getTrace(PageProcessInstances.class); private static final String DOT_CLASS = PageProcessInstances.class.getName() + "."; private static final String OPERATION_STOP_PROCESS_INSTANCES = DOT_CLASS + "stopProcessInstances"; public static final String OPERATION_STOP_PROCESS_INSTANCE = DOT_CLASS + "stopProcessInstance"; private static final String OPERATION_DELETE_PROCESS_INSTANCES = DOT_CLASS + "deleteProcessInstances"; private static final String OPERATION_DELETE_PROCESS_INSTANCE = DOT_CLASS + "deleteProcessInstance"; public PageProcessInstances(boolean requestedBy, boolean requestedFor) { this.requestedBy = requestedBy; this.requestedFor = requestedFor; initLayout(); } private void initLayout() { Form mainForm = new Form(ID_MAIN_FORM); add(mainForm); ISortableDataProvider<ProcessInstanceDto, String> provider = new ProcessInstanceDtoProvider(PageProcessInstances.this, requestedBy, requestedFor); ProcessInstancesPanel panel = new ProcessInstancesPanel(ID_PROCESS_INSTANCES_TABLE, provider, UserProfileStorage.TableId.PAGE_WORKFLOW_REQUESTS, (int) getItemsPerPage(UserProfileStorage.TableId.PAGE_WORKFLOW_REQUESTS), ProcessInstancesPanel.View.FULL_LIST, null); panel.setOutputMarkupId(true); mainForm.add(panel); initItemButtons(mainForm); } private void initItemButtons(Form mainForm) { AjaxButton back = new AjaxButton(ID_BACK, createStringResource("pageProcessInstances.button.back")) { @Override public void onClick(AjaxRequestTarget target) { redirectBack(); } }; mainForm.add(back); AjaxButton stop = new AjaxButton(ID_STOP, createStringResource("pageProcessInstances.button.stop")) { @Override public void onClick(AjaxRequestTarget target) { stopProcessInstancesPerformed(target); } @Override public boolean isVisible() { return !requestedFor; } }; mainForm.add(stop); AjaxButton delete = new AjaxButton(ID_DELETE, createStringResource("pageProcessInstances.button.delete")) { @Override public void onClick(AjaxRequestTarget target) { deleteProcessInstancesPerformed(target); } @Override public boolean isVisible() { return !requestedFor; } }; mainForm.add(delete); } private BoxedTablePanel<?> getTable() { return ((ProcessInstancesPanel) get(createComponentPath(ID_MAIN_FORM, ID_PROCESS_INSTANCES_TABLE))).getTablePanel(); } private boolean isSomeItemSelected(List<ProcessInstanceDto> instances, boolean stoppable, AjaxRequestTarget target) { if (!instances.isEmpty()) { return true; } if (stoppable) { warn(getString("pageProcessInstances.message.noStoppableItemSelected")); } else { warn(getString("pageProcessInstances.message.noItemSelected")); } target.add(getFeedbackPanel()); return false; } private void itemDetailsPerformed(AjaxRequestTarget target, String taskOid) { PageParameters parameters = new PageParameters(); parameters.add(OnePageParameterEncoder.PARAMETER, taskOid); navigateToNext(PageTaskEdit.class, parameters); } private void stopProcessInstancesPerformed(AjaxRequestTarget target) { MidPointPrincipal user = SecurityUtils.getPrincipalUser(); List<ProcessInstanceDto> selectedStoppableInstances = new ArrayList<>(); for (Selectable row : WebComponentUtil.getSelectedData(getTable())) { ProcessInstanceDto instance = (ProcessInstanceDto) row; if (instance.getEndTimestamp() == null) { selectedStoppableInstances.add(instance); } } if (!isSomeItemSelected(selectedStoppableInstances, true, target)) { return; } OperationResult result = new OperationResult(OPERATION_STOP_PROCESS_INSTANCES); WorkflowService workflowService = getWorkflowService(); for (ProcessInstanceDto instance : selectedStoppableInstances) { try { workflowService.stopProcessInstance(instance.getProcessInstanceId(), WebComponentUtil.getOrigStringFromPoly(user.getName()), result); } catch (SchemaException|ObjectNotFoundException|SecurityViolationException|RuntimeException ex) { result.createSubresult(OPERATION_STOP_PROCESS_INSTANCE).recordPartialError("Couldn't stop process instance " + instance.getName(), ex); } } if (result.isUnknown()) { result.recomputeStatus(); } if (result.isSuccess()) { result.recordStatus(OperationResultStatus.SUCCESS, "Selected process instance(s) have been successfully stopped."); } showResult(result); ProcessInstanceDtoProvider provider = (ProcessInstanceDtoProvider) getTable().getDataTable().getDataProvider(); provider.clearCache(); //refresh feedback and table target.add(getFeedbackPanel()); target.add(getTable()); } private void deleteProcessInstancesPerformed(AjaxRequestTarget target) { List<ProcessInstanceDto> processInstanceDtoList = WebComponentUtil.getSelectedData(getTable()); if (!isSomeItemSelected(processInstanceDtoList, false, target)) { return; } Task opTask = createSimpleTask(OPERATION_DELETE_PROCESS_INSTANCES); OperationResult result = opTask.getResult(); ModelService modelService = getModelService(); for (ProcessInstanceDto processInstanceDto : processInstanceDtoList) { String taskOid = processInstanceDto.getTaskOid(); try { ObjectDelta<? extends ObjectType> deleteDelta = ObjectDelta.createDeleteDelta(TaskType.class, taskOid, getPrismContext()); modelService.executeChanges(Collections.<ObjectDelta<? extends ObjectType>>singletonList(deleteDelta), null, opTask, result); } catch (CommonException|RuntimeException e) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't delete task (process instance) {}", e, taskOid); } } if (result.isUnknown()) { result.recomputeStatus(); } if (result.isSuccess()) { result.recordStatus(OperationResultStatus.SUCCESS, "Selected process instance(s) have been successfully deleted."); } showResult(result); ProcessInstanceDtoProvider provider = (ProcessInstanceDtoProvider) getTable().getDataTable().getDataProvider(); provider.clearCache(); //refresh feedback and table target.add(getFeedbackPanel()); target.add(getTable()); } }