/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Copyright (c) 2013, MPL CodeInside http://codeinside.ru */ package ru.codeinside.gses.beans; import com.google.common.base.Function; import com.google.common.collect.Lists; import org.activiti.engine.ActivitiTaskAlreadyClaimedException; import org.activiti.engine.ProcessEngine; import org.activiti.engine.RepositoryService; import org.activiti.engine.TaskService; import org.activiti.engine.form.StartFormData; import org.activiti.engine.identity.Group; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.task.Task; import ru.codeinside.adm.AdminServiceProvider; import ru.codeinside.gses.service.Functions; import ru.codeinside.gses.service.PF; import ru.codeinside.gses.webui.Flash; import ru.codeinside.gses.webui.utils.ActivitiUtils; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; public class ActivitiBean { public static final String FORCED_DELETE = "forced delete"; private static ActivitiBean activitiBean = new ActivitiBean(); public static ActivitiBean get() { return activitiBean; } public ProcessDefinition getProcessDefinitionByDeployment(final String deploymentId, String user) { return Functions.withRepository(user, new Function<RepositoryService, ProcessDefinition>() { public ProcessDefinition apply(RepositoryService srv) { return srv.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult(); } }); } public ProcessDefinition getProcessDefinition(final String processDefinitionId, String user) { return Functions.withRepository(user, new Function<RepositoryService, ProcessDefinition>() { public ProcessDefinition apply(RepositoryService srv) { return srv.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult(); } }); } public Deployment deploy(final String fileName, final byte[] bytes) { return Functions.withRepository(new Function<RepositoryService, Deployment>() { public Deployment apply(RepositoryService repositoryService) { InputStream is = new ByteArrayInputStream(bytes); String adaptedName = ActivitiUtils.makeAdaptedActivitiName(fileName); Deployment deploy = repositoryService.createDeployment().name(adaptedName) .addInputStream(adaptedName, is).deploy(); try { is.close(); } catch (IOException e) { e.printStackTrace(); } return deploy; } }); } public boolean start(final String processDefinitionId) { return Functions.withEngine(new PF<Boolean>() { private static final long serialVersionUID = 1L; public Boolean apply(ProcessEngine engine) { StartFormData startFormData = engine.getFormService().getStartFormData(processDefinitionId); if (!hasStartFormData(startFormData)) { engine.getRepositoryService().createProcessDefinitionQuery() .processDefinitionId(processDefinitionId).singleResult(); return engine.getRuntimeService().startProcessInstanceById(processDefinitionId) != null; } return false; } }); } /** * Назначить этап taskId на исполнителя toUserLogin. Форисровать переназначение если forceAssign == true. */ public String claim(final String taskId, final String toUserLogin, final String byUser, final boolean forceAssign) { return Functions.withEngine(new PF<String>() { private static final long serialVersionUID = 1L; public String apply(final ProcessEngine engine) { final TaskService taskService = engine.getTaskService(); final Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); if (task == null) { return "Этап уже исполнен!"; } try { checkCandidates(engine, toUserLogin, task); } catch (Exception e) { Logger.getLogger(getClass().getName()).log(Level.INFO, "claim fail", e); return e.getMessage(); } if (forceAssign) { taskService.setAssignee(task.getId(), toUserLogin); } else { try { taskService.claim(task.getId(), toUserLogin); } catch (ActivitiTaskAlreadyClaimedException e) { return "Этап уже назначен исполнителю!"; } catch (RuntimeException e) { Logger.getLogger(getClass().getName()).log(Level.INFO, "claim fail", e); return e.getMessage(); } } // TODO: либо обработать событие TaskListener.EVENTNAME_ASSIGNMENT AdminServiceProvider.get().saveBidAssignment(engine, task.getProcessInstanceId(), toUserLogin); return ""; } }); } private void checkCandidates(ProcessEngine engine, String user, Task task) throws Exception { if (user.equals(task.getAssignee())) { return; } TaskService taskService = engine.getTaskService(); boolean canClaim = taskService.createTaskQuery().taskCandidateUser(user).taskId(task.getId()) .count() == 1; List<String> candidateGroups = Lists.newArrayList(); for (Group g : engine.getIdentityService().createGroupQuery().groupMember(user).list()) { candidateGroups.add(g.getId()); } boolean canClaimByGroup = taskService.createTaskQuery().taskCandidateGroupIn(candidateGroups) .taskId(task.getId()).count() == 1; if (!canClaim && !canClaimByGroup) { throw new Exception("У Вас нет прав доступа к этому этапу"); } } private boolean hasStartFormData(StartFormData startFormData) { return (startFormData != null) && // (((startFormData.getFormProperties() != null) && // (startFormData.getFormProperties().size() > 0)) || (startFormData.getFormKey() != null)); } public String deleteProcessInstance(final String taskId, final String deleteReason) { return Functions.withEngine(new PF<String>() { private static final long serialVersionUID = 1L; public String apply(final ProcessEngine engine) { engine.getIdentityService().setAuthenticatedUserId(Flash.login()); Task task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult(); engine.getRuntimeService().deleteProcessInstance(task.getProcessInstanceId(), deleteReason); return null; } }); } }