提交 7b65d184 编写于 作者: T trademak

Applied patch ACT-831 to trunk also

上级 f7cbea60
......@@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.List;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.impl.bpmn.data.AbstractDataAssociation;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.pvm.PvmProcessInstance;
......@@ -36,11 +37,17 @@ public class CallActivityBehavior extends AbstractBpmnActivityBehavior implement
protected String processDefinitonKey;
private List<AbstractDataAssociation> dataInputAssociations = new ArrayList<AbstractDataAssociation>();
private List<AbstractDataAssociation> dataOutputAssociations = new ArrayList<AbstractDataAssociation>();
private Expression processDefinitionExpression;
public CallActivityBehavior(String processDefinitionKey) {
this.processDefinitonKey = processDefinitionKey;
}
public CallActivityBehavior(Expression processDefinitionExpression) {
super();
this.processDefinitionExpression = processDefinitionExpression;
}
public void addDataInputAssociation(AbstractDataAssociation dataInputAssociation) {
this.dataInputAssociations.add(dataInputAssociation);
}
......@@ -50,6 +57,11 @@ public class CallActivityBehavior extends AbstractBpmnActivityBehavior implement
}
public void execute(ActivityExecution execution) throws Exception {
if ((processDefinitonKey == null) && (processDefinitionExpression != null)) {
processDefinitonKey = (String) processDefinitionExpression.getValue(execution);
}
ProcessDefinitionImpl processDefinition = Context
.getProcessEngineConfiguration()
.getDeploymentCache()
......
......@@ -2403,7 +2403,13 @@ public class BpmnParse extends Parse {
addError("Missing attribute 'calledElement'", callActivityElement);
}
CallActivityBehavior callActivityBehaviour = new CallActivityBehavior(calledElement);
CallActivityBehavior callActivityBehaviour = null;
String expressionRegex = "\\$+\\{+.+\\}";
if (calledElement.matches(expressionRegex)) {
callActivityBehaviour = new CallActivityBehavior(expressionManager.createExpression(calledElement));
} else {
callActivityBehaviour = new CallActivityBehavior(calledElement);
}
Element extentionsElement = callActivityElement.element("extensionElements");
if (extentionsElement != null) {
......
......@@ -146,7 +146,7 @@
<xsd:complexType name="tCallActivity">
<xsd:complexContent>
<xsd:extension base="tActivity">
<xsd:attribute name="calledElement" type="xsd:QName" use="optional"/>
<xsd:attribute name="calledElement" type="xsd:string" use="optional"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
......
......@@ -60,6 +60,36 @@ public class CallActivityAdvancedTest extends PluggableActivitiTestCase {
assertProcessEnded(processInstance.getId());
}
@Deployment(resources = { "org/activiti/engine/test/bpmn/callactivity/CallActivity.testCallSimpleSubProcessWithExpressions.bpmn20.xml",
"org/activiti/engine/test/bpmn/callactivity/simpleSubProcess.bpmn20.xml" })
public void testCallSimpleSubProcessWithExpressions() {
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("callSimpleSubProcess");
// one task in the subprocess should be active after starting the process
// instance
TaskQuery taskQuery = taskService.createTaskQuery();
Task taskBeforeSubProcess = taskQuery.singleResult();
assertEquals("Task before subprocess", taskBeforeSubProcess.getName());
// Completing the task continues the process which leads to calling the
// subprocess. The sub process we want to call is passed in as a variable
// into this task
taskService.setVariable(taskBeforeSubProcess.getId(), "simpleSubProcessExpression", "simpleSubProcess");
taskService.complete(taskBeforeSubProcess.getId());
Task taskInSubProcess = taskQuery.singleResult();
assertEquals("Task in subprocess", taskInSubProcess.getName());
// Completing the task in the subprocess, finishes the subprocess
taskService.complete(taskInSubProcess.getId());
Task taskAfterSubProcess = taskQuery.singleResult();
assertEquals("Task after subprocess", taskAfterSubProcess.getName());
// Completing this task end the process instance
taskService.complete(taskAfterSubProcess.getId());
assertProcessEnded(processInstance.getId());
}
/**
* Test case for a possible tricky case: reaching the end event
* of the subprocess leads to an end event in the super process instance.
......
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="callSimpleSubProcess">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="taskBeforeSubProcess" />
<userTask id="taskBeforeSubProcess" name="Task before subprocess" />
<sequenceFlow id="flow2" sourceRef="taskBeforeSubProcess" targetRef="callSubProcess" />
<callActivity id="callSubProcess" calledElement="${simpleSubProcessExpression}" />
<sequenceFlow id="flow3" sourceRef="callSubProcess" targetRef="taskAfterSubProcess" />
<userTask id="taskAfterSubProcess" name="Task after subprocess" />
<sequenceFlow id="flow4" sourceRef="taskAfterSubProcess" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
\ No newline at end of file
/*
* 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.spring.test.expression.callactivity;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.activiti.engine.test.Deployment;
import org.activiti.spring.impl.test.SpringActivitiTestCase;
import org.springframework.test.context.ContextConfiguration;
/**
* The CallActivityBasedOnSpringBeansExpressionTest is used to test dynamically wiring in the calledElement
* in the callActivity task. This test case helps verify that we do not have to hard code the sub process
* definition key within the process.
*
* @author Sang Venkatraman
*/
@ContextConfiguration("classpath:org/activiti/spring/test/expression/callactivity/testCallActivityByExpression-context.xml")
public class CallActivityBasedOnSpringBeansExpressionTest extends SpringActivitiTestCase {
@Deployment(resources = {
"org/activiti/spring/test/expression/callactivity/CallActivityBasedOnSpringBeansExpressionTest.testCallActivityByExpression.bpmn20.xml",
"org/activiti/spring/test/expression/callactivity/simpleSubProcess.bpmn20.xml" })
public void testCallActivityByExpression() throws Exception {
// Start process (main)
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testCallActivityByExpression");
// one task in the subprocess should be active after starting the process instance
TaskQuery taskQuery = taskService.createTaskQuery();
Task taskBeforeSubProcess = taskQuery.singleResult();
assertEquals("Task before subprocess", taskBeforeSubProcess.getName());
// Completing the task continues the process which leads to calling the subprocess. The sub process we want to
// call is passed in as a variable into this task
taskService.complete(taskBeforeSubProcess.getId());
Task taskInSubProcess = taskQuery.singleResult();
assertEquals("Task in subprocess", taskInSubProcess.getName());
// Completing the task in the subprocess, finishes the subprocess
taskService.complete(taskInSubProcess.getId());
Task taskAfterSubProcess = taskQuery.singleResult();
assertEquals("Task after subprocess", taskAfterSubProcess.getName());
// Completing this task end the process instance
taskService.complete(taskAfterSubProcess.getId());
assertProcessEnded(processInstance.getId());
}
}
/*
* 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.spring.test.expression.callactivity;
/**
* The NextProcessExecutionEvaluator class provides the name of the sub process to be executed next. This allows
* us to test dynamically wire in the calledElement in the callActivity task. In an actual implementation there would
* be business logic here to determine which process to execute in the callActivity task.
*
* @author Sang Venkatraman
*
*/
public class NextProcessExecutionEvaluator {
public String returnProcessDefinitionToCall() {
//some business logic here
return "simpleSubProcess";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="testCallActivityByExpression">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="taskBeforeSubProcess" />
<userTask id="taskBeforeSubProcess" name="Task before subprocess" />
<sequenceFlow id="flow2" sourceRef="taskBeforeSubProcess" targetRef="callSubProcess" />
<callActivity id="callSubProcess" calledElement="${nextProcessEvaluator.returnProcessDefinitionToCall()}" />
<sequenceFlow id="flow3" sourceRef="callSubProcess" targetRef="taskAfterSubProcess" />
<userTask id="taskAfterSubProcess" name="Task after subprocess" />
<sequenceFlow id="flow4" sourceRef="taskAfterSubProcess" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="simpleSubProcess">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="task" />
<userTask id="task" name="Task in subprocess" />
<sequenceFlow id="flow2" sourceRef="task" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="nextProcessEvaluator" class="org.activiti.spring.test.expression.callactivity.NextProcessExecutionEvaluator" />
<bean id="bean2" class="org.activiti.spring.test.servicetask.SentenceGenerator" />
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
</bean>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
</beans>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册