/* * Copyright (c) NASK, NCSC * * This file is part of HoneySpider Network 2.1. * * This is a free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pl.nask.hsn2.activiti; import java.util.List; import org.activiti.engine.impl.pvm.PvmExecution; import org.activiti.engine.impl.pvm.runtime.ExecutionImpl; import pl.nask.hsn2.workflow.engine.ProcessContext; public final class ExtendedExecutionImpl extends ExecutionImpl { // variable names public static final String TASK_ID = "task_id"; public static final String PARENT_EXECUTION = "parent_execution"; public static final String CHILD_EXECUTIONS = "child_executions"; public static final String PROCESS_CONTEXT= "process_context"; private static final long serialVersionUID = -3070016232270340831L; private ProcessContext processContext; private ExtendedExecutionImpl parentExecution; private Integer taskId; private List<ExtendedExecutionImpl> childExecutions; @Override protected ExecutionImpl newExecution() { return new ExtendedExecutionImpl(); } @Override protected void collectActiveActivityIds(List<String> activeActivityIds) { super.collectActiveActivityIds(activeActivityIds); if (subProcessInstance != null) { ((ExtendedExecutionImpl) subProcessInstance).collectActiveActivityIds(activeActivityIds); } List<ExtendedExecutionImpl> executions = getChildProcesses(); if (executions != null) { for (ExtendedExecutionImpl execution: executions) { execution.collectActiveActivityIds(activeActivityIds); } } } @Override public ExtendedExecutionImpl findExecution(String activityId) { ExtendedExecutionImpl res = (ExtendedExecutionImpl) super.findExecution(activityId); if (res == null) { res = findExecutionInChildProcesses(activityId); } if (res == null && subProcessInstance != null) { return (ExtendedExecutionImpl) subProcessInstance.findExecution(activityId); } else { return res; } } private List<ExtendedExecutionImpl> getChildProcesses() { return childExecutions; } private ExtendedExecutionImpl findExecutionInChildProcesses(String activityId) { // TODO: string repeated in ExecutionWrapper! // FIXME: casting PvmExecution to ExecutionImpl! List<ExtendedExecutionImpl> executions = getChildProcesses(); if (executions == null) return null; for (ExtendedExecutionImpl execution: executions) { ExtendedExecutionImpl exec = execution.findExecution(activityId); if (exec != null) return exec; } return null; } @Override public void setVariable(String variableName, Object value) { if (getParent() == null || getVariableLocal(variableName) != null) { this.setVariableLocal(variableName, value); } else { getParent().setVariable(variableName, value); } } @Override public Object getVariable(String variableName) { Object o = this.getVariableLocal(variableName); if (o == null && getParent() != null) { o = getParent().getVariable(variableName); } return o; } @Override public Object setVariableLocal(String variableName, Object value) { if (PROCESS_CONTEXT.equals(variableName)) { processContext = (ProcessContext) value; } else if (PARENT_EXECUTION.equals(variableName)) { parentExecution = (ExtendedExecutionImpl) value; } else if (TASK_ID.equals(variableName)) { taskId = (Integer) value; } else if (CHILD_EXECUTIONS.equals(variableName)) { childExecutions = (List<ExtendedExecutionImpl>) value; } else { ensureVariablesInitialized(); setVariableLocally(variableName, value); } return value; } @Override public Object getVariableLocal(Object variableName) { if (PROCESS_CONTEXT.equals(variableName)) { return processContext; } if (PARENT_EXECUTION.equals(variableName)) { return parentExecution; } if (TASK_ID.equals(variableName)) { return taskId; } if (CHILD_EXECUTIONS.equals(variableName)) { return childExecutions; } ensureVariablesInitialized(); return variables.get(variableName); } @Override /** * Overridden to enable output/wait */ public void end() { super.end(); // notify all active waits in parent process, that the execution is ended. PvmExecution superProcess = getParentProcess(); if (superProcess != null) { superProcess.signal("notify", null); } } @Override public void destroy() { super.destroy(); } @Override public void remove() { super.remove(); ExtendedExecutionImpl parentProcess = (ExtendedExecutionImpl) getParentProcess(); if (parentProcess != null) { parentProcess.getChildProcesses().remove(this); } } private PvmExecution getParentProcess() { return parentExecution; } // TODO: an extension would be to return a collection of executions which match the condition public PvmExecution findExecutionWithVariable(String variableName, Object value) { Object var = getVariableLocal(variableName); PvmExecution ret = null; if (value.equals(var)) ret = this; synchronized(this) { // check nested executions, child processes and a subprocess // nested executions if (ret == null) ret = findExecutionWithVariable(executions, variableName, value); // child processes if (ret == null) ret = findExecutionWithVariable(getChildProcesses(), variableName, value); // a subprocess if (ret == null && subProcessInstance != null) ret = ((ExtendedExecutionImpl) subProcessInstance).findExecutionWithVariable(variableName, value); } return ret; } private PvmExecution findExecutionWithVariable(List<? extends ExecutionImpl> executions, String variableName, Object value) { if (executions != null) { for (ExecutionImpl exec: executions) { if (!exec.isEnded()) { PvmExecution ret = ((ExtendedExecutionImpl) exec).findExecutionWithVariable(variableName, value); if (ret != null) return ret; } } } return null; } public PvmExecution findExecuionWithTaskId(int taskId) { return findExecutionWithVariable(TASK_ID, taskId); } }