/* 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 org.activiti.engine.test.db;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.test.PluggableActivitiTestCase;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.Deployment;
/**
* @author Tijs Rademakers
*/
public class VariableScopeTest extends PluggableActivitiTestCase {
@Deployment
public void testVariableScope() {
// After starting the process, the task in the subprocess should be active
Map<String, Object> varMap = new HashMap<String, Object>();
varMap.put("test", "test");
ProcessInstance pi = runtimeService.startProcessInstanceByKey("simpleSubProcess", varMap);
Task subProcessTask = taskService.createTaskQuery()
.processInstanceId(pi.getId())
.singleResult();
assertEquals("Task in subprocess", subProcessTask.getName());
// get variables for execution id user task, should return the new value of variable test --> test2
assertEquals("test2", runtimeService.getVariable(subProcessTask.getExecutionId(), "test"));
assertEquals("test2", runtimeService.getVariables(subProcessTask.getExecutionId()).get("test"));
// get variables for process instance id, should return the initial value of variable test --> test
assertEquals("test", runtimeService.getVariable(pi.getId(), "test"));
assertEquals("test", runtimeService.getVariables(pi.getId()).get("test"));
runtimeService.setVariableLocal(subProcessTask.getExecutionId(), "test", "test3");
// get variables for execution id user task, should return the new value of variable test --> test3
assertEquals("test3", runtimeService.getVariable(subProcessTask.getExecutionId(), "test"));
assertEquals("test3", runtimeService.getVariables(subProcessTask.getExecutionId()).get("test"));
// get variables for process instance id, should still return the initial value of variable test --> test
assertEquals("test", runtimeService.getVariable(pi.getId(), "test"));
assertEquals("test", runtimeService.getVariables(pi.getId()).get("test"));
runtimeService.setVariable(pi.getId(), "test", "test4");
// get variables for execution id user task, should return the old value of variable test --> test3
assertEquals("test3", runtimeService.getVariable(subProcessTask.getExecutionId(), "test"));
assertEquals("test3", runtimeService.getVariables(subProcessTask.getExecutionId()).get("test"));
// get variables for process instance id, should also return the initial value of variable test --> test4
assertEquals("test4", runtimeService.getVariable(pi.getId(), "test"));
assertEquals("test4", runtimeService.getVariables(pi.getId()).get("test"));
// After completing the task in the subprocess,
// the subprocess scope is destroyed and the complete process ends
taskService.complete(subProcessTask.getId());
}
/**
* A testcase to produce and fix issue ACT-862.
* @author Roman Smirnov
* @author Christian Lipphardt
*/
@Deployment
public void testVariableNamesScope() {
// After starting the process, the task in the subprocess should be active
Map<String, Object> varMap = new HashMap<String, Object>();
varMap.put("test", "test");
varMap.put("helloWorld", "helloWorld");
ProcessInstance pi = runtimeService.startProcessInstanceByKey("simpleSubProcess", varMap);
Task subProcessTask = taskService.createTaskQuery()
.processInstanceId(pi.getId())
.singleResult();
runtimeService.setVariableLocal(pi.getProcessInstanceId(), "mainProcessLocalVariable", "Hello World");
assertEquals("Task in subprocess", subProcessTask.getName());
runtimeService.setVariableLocal(subProcessTask.getExecutionId(), "subProcessLocalVariable", "Hello SubProcess");
// Returns a set of local variablenames of pi
List<String> result = processEngineConfiguration.
getCommandExecutorTxRequired().
execute(new GetVariableNamesCommand(pi.getProcessInstanceId(), true));
// pi contains local the variablenames "test", "helloWorld" and "mainProcessLocalVariable" but not "subProcessLocalVariable"
assertTrue(result.contains("test"));
assertTrue(result.contains("helloWorld"));
assertTrue(result.contains("mainProcessLocalVariable"));
assertFalse(result.contains("subProcessLocalVariable"));
// Returns a set of global variablenames of pi
result = processEngineConfiguration.
getCommandExecutorTxRequired().
execute(new GetVariableNamesCommand(pi.getProcessInstanceId(), false));
// pi contains global the variablenames "test", "helloWorld" and "mainProcessLocalVariable" but not "subProcessLocalVariable"
assertTrue(result.contains("test"));
assertTrue(result.contains("mainProcessLocalVariable"));
assertTrue(result.contains("helloWorld"));
assertFalse(result.contains("subProcessLocalVariable"));
// Returns a set of local variablenames of subProcessTask execution
result = processEngineConfiguration.
getCommandExecutorTxRequired().
execute(new GetVariableNamesCommand(subProcessTask.getExecutionId(), true));
// subProcessTask execution contains local the variablenames "test", "subProcessLocalVariable" but not "helloWorld" and "mainProcessLocalVariable"
assertTrue(result.contains("test")); // the variable "test" was set locally by SetLocalVariableTask
assertTrue(result.contains("subProcessLocalVariable"));
assertFalse(result.contains("helloWorld"));
assertFalse(result.contains("mainProcessLocalVariable"));
// Returns a set of global variablenames of subProcessTask execution
result = processEngineConfiguration.
getCommandExecutorTxRequired().
execute(new GetVariableNamesCommand(subProcessTask.getExecutionId(), false));
// subProcessTask execution contains global all defined variablenames
assertTrue(result.contains("test")); // the variable "test" was set locally by SetLocalVariableTask
assertTrue(result.contains("subProcessLocalVariable"));
assertTrue(result.contains("helloWorld"));
assertTrue(result.contains("mainProcessLocalVariable"));
taskService.complete(subProcessTask.getId());
}
/**
* A command to get the names of the variables
* @author Roman Smirnov
* @author Christian Lipphardt
*/
private class GetVariableNamesCommand implements Command<List<String>> {
private String executionId;
private boolean isLocal;
public GetVariableNamesCommand(String executionId, boolean isLocal) {
this.executionId = executionId;
this.isLocal = isLocal;
}
public List<String> execute(CommandContext commandContext) {
if(executionId == null) {
throw new ActivitiException("executionId is null");
}
ExecutionEntity execution = commandContext
.getExecutionManager()
.findExecutionById(executionId);
if (execution==null) {
throw new ActivitiException("execution "+executionId+" doesn't exist");
}
List<String> executionVariables;
if (isLocal) {
executionVariables = new ArrayList<String>(execution.getVariableNamesLocal());
} else {
executionVariables = new ArrayList<String>(execution.getVariableNames());
}
return executionVariables;
}
}
}