提交 46876282 编写于 作者: T Tijs Rademakers

Merge branch 'master' of https://github.com/roberthafner/Activiti

......@@ -168,6 +168,7 @@ public interface BpmnXMLConstants {
public static final String ATTRIBUTE_TASK_SERVICE_DELEGATEEXPRESSION = "delegateExpression";
public static final String ATTRIBUTE_TASK_SERVICE_RESULTVARIABLE = "resultVariableName";
public static final String ATTRIBUTE_TASK_SERVICE_EXTENSIONID = "extensionId";
public static final String ATTRIBUTE_TASK_SERVICE_SKIP_EXPRESSION = "skipExpression";
public static final String ATTRIBUTE_TASK_USER_ASSIGNEE = "assignee";
public static final String ATTRIBUTE_TASK_USER_OWNER = "owner";
......@@ -176,6 +177,7 @@ public interface BpmnXMLConstants {
public static final String ATTRIBUTE_TASK_USER_DUEDATE = "dueDate";
public static final String ATTRIBUTE_TASK_USER_CATEGORY = "category";
public static final String ATTRIBUTE_TASK_USER_PRIORITY = "priority";
public static final String ATTRIBUTE_TASK_USER_SKIP_EXPRESSION = "skipExpression";
public static final String ATTRIBUTE_TASK_RULE_VARIABLES_INPUT = "ruleVariablesInput";
public static final String ATTRIBUTE_TASK_RULE_RESULT_VARIABLE = "resultVariable";
......@@ -194,6 +196,7 @@ public interface BpmnXMLConstants {
public static final String ELEMENT_FLOW_CONDITION = "conditionExpression";
public static final String ATTRIBUTE_FLOW_SOURCE_REF = "sourceRef";
public static final String ATTRIBUTE_FLOW_TARGET_REF = "targetRef";
public static final String ATTRIBUTE_FLOW_SKIP_EXPRESSION = "skipExpression";
public static final String ELEMENT_TEXT_ANNOTATION = "textAnnotation";
public static final String ATTRIBUTE_TEXTFORMAT = "textFormat";
......
......@@ -42,6 +42,7 @@ public class SequenceFlowXMLConverter extends BaseBpmnXMLConverter {
sequenceFlow.setSourceRef(xtr.getAttributeValue(null, ATTRIBUTE_FLOW_SOURCE_REF));
sequenceFlow.setTargetRef(xtr.getAttributeValue(null, ATTRIBUTE_FLOW_TARGET_REF));
sequenceFlow.setName(xtr.getAttributeValue(null, ATTRIBUTE_NAME));
sequenceFlow.setSkipExpression(xtr.getAttributeValue(null, ATTRIBUTE_FLOW_SKIP_EXPRESSION));
parseChildElements(getXMLElementName(), sequenceFlow, model, xtr);
......@@ -53,6 +54,10 @@ public class SequenceFlowXMLConverter extends BaseBpmnXMLConverter {
SequenceFlow sequenceFlow = (SequenceFlow) element;
writeDefaultAttribute(ATTRIBUTE_FLOW_SOURCE_REF, sequenceFlow.getSourceRef(), xtw);
writeDefaultAttribute(ATTRIBUTE_FLOW_TARGET_REF, sequenceFlow.getTargetRef(), xtw);
if(StringUtils.isNotEmpty(sequenceFlow.getSkipExpression()))
{
writeDefaultAttribute(ATTRIBUTE_FLOW_SKIP_EXPRESSION, sequenceFlow.getSkipExpression(), xtw);
}
}
@Override
......
......@@ -67,6 +67,9 @@ public class ServiceTaskXMLConverter extends BaseBpmnXMLConverter {
serviceTask.setType(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TYPE));
serviceTask.setExtensionId(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_EXTENSIONID));
if (StringUtils.isNotEmpty(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_SKIP_EXPRESSION))) {
serviceTask.setSkipExpression(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_SKIP_EXPRESSION));
}
parseChildElements(getXMLElementName(), serviceTask, model, xtr);
return serviceTask;
......@@ -94,6 +97,10 @@ public class ServiceTaskXMLConverter extends BaseBpmnXMLConverter {
if (StringUtils.isNotEmpty(serviceTask.getExtensionId())) {
writeQualifiedAttribute(ATTRIBUTE_TASK_SERVICE_EXTENSIONID, serviceTask.getExtensionId(), xtw);
}
if(StringUtils.isNotEmpty(serviceTask.getSkipExpression()))
{
writeQualifiedAttribute(ATTRIBUTE_TASK_SERVICE_SKIP_EXPRESSION, serviceTask.getSkipExpression(), xtw);
}
}
@Override
......
......@@ -48,7 +48,8 @@ public class UserTaskXMLConverter extends BaseBpmnXMLConverter {
new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_PRIORITY),
new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATEUSERS),
new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CANDIDATEGROUPS),
new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CATEGORY)
new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_CATEGORY),
new ExtensionAttribute(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_SKIP_EXPRESSION)
);
public UserTaskXMLConverter() {
......@@ -100,6 +101,11 @@ public class UserTaskXMLConverter extends BaseBpmnXMLConverter {
userTask.getCandidateGroups().addAll(parseDelimitedList(expression));
}
if (StringUtils.isNotEmpty(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_SKIP_EXPRESSION))) {
String expression = xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_USER_SKIP_EXPRESSION);
userTask.setSkipExpression(expression);
}
BpmnXMLUtil.addCustomAttributes(xtr, userTask, defaultElementAttributes,
defaultActivityAttributes, defaultUserTaskAttributes);
......@@ -122,6 +128,10 @@ public class UserTaskXMLConverter extends BaseBpmnXMLConverter {
if (userTask.getPriority() != null) {
writeQualifiedAttribute(ATTRIBUTE_TASK_USER_PRIORITY, userTask.getPriority().toString(), xtw);
}
if(null != userTask.getSkipExpression())
{
writeQualifiedAttribute(ATTRIBUTE_TASK_USER_SKIP_EXPRESSION, userTask.getSkipExpression(), xtw);
}
// write custom attributes
BpmnXMLUtil.writeCustomAttributes(userTask.getAttributes().values(), xtw, defaultElementAttributes,
defaultActivityAttributes, defaultUserTaskAttributes);
......
......@@ -1373,6 +1373,7 @@
<xsd:attribute name="sourceRef" type="xsd:IDREF" use="required"/>
<xsd:attribute name="targetRef" type="xsd:IDREF" use="required"/>
<xsd:attribute name="isImmediate" type="xsd:boolean" use="optional"/>
<xsd:attribute name="skipExpression" type="xsd:string" use="optional"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
......@@ -1383,6 +1384,7 @@
<xsd:extension base="tTask">
<xsd:attribute name="implementation" type="tImplementation" default="##WebService"/>
<xsd:attribute name="operationRef" type="xsd:QName" use="optional"/>
<xsd:attribute name="skipExpression" type="xsd:string" use="optional"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
......@@ -1555,6 +1557,7 @@
<xsd:element ref="rendering" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="implementation" type="tImplementation" default="##unspecified"/>
<xsd:attribute name="skipExpression" type="xsd:string" use="optional"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
......
......@@ -23,6 +23,7 @@ public class SequenceFlow extends FlowElement {
protected String conditionExpression;
protected String sourceRef;
protected String targetRef;
protected String skipExpression;
public SequenceFlow() {
......@@ -51,6 +52,12 @@ public class SequenceFlow extends FlowElement {
public void setTargetRef(String targetRef) {
this.targetRef = targetRef;
}
public String getSkipExpression() {
return skipExpression;
}
public void setSkipExpression(String skipExpression) {
this.skipExpression = skipExpression;
}
public String toString() {
return sourceRef + " --> " + targetRef;
}
......
......@@ -21,7 +21,7 @@ import java.util.List;
public class ServiceTask extends Task {
public static final String MAIL_TASK = "mail";
protected String implementation;
protected String implementationType;
protected String resultVariableName;
......@@ -30,6 +30,7 @@ public class ServiceTask extends Task {
protected String extensionId;
protected List<FieldExtension> fieldExtensions = new ArrayList<FieldExtension>();
protected List<CustomProperty> customProperties = new ArrayList<CustomProperty>();
protected String skipExpression;
public String getImplementation() {
return implementation;
......@@ -83,12 +84,20 @@ public class ServiceTask extends Task {
return extensionId != null && !extensionId.isEmpty();
}
public String getSkipExpression() {
return skipExpression;
}
public void setSkipExpression(String skipExpression) {
this.skipExpression = skipExpression;
}
public ServiceTask clone() {
ServiceTask clone = new ServiceTask();
clone.setValues(this);
return clone;
}
public void setValues(ServiceTask otherElement) {
super.setValues(otherElement);
setImplementation(otherElement.getImplementation());
......@@ -97,14 +106,14 @@ public class ServiceTask extends Task {
setType(otherElement.getType());
setOperationRef(otherElement.getOperationRef());
setExtensionId(otherElement.getExtensionId());
fieldExtensions = new ArrayList<FieldExtension>();
if (otherElement.getFieldExtensions() != null && !otherElement.getFieldExtensions().isEmpty()) {
for (FieldExtension extension : otherElement.getFieldExtensions()) {
fieldExtensions.add(extension.clone());
}
}
customProperties = new ArrayList<CustomProperty>();
if (otherElement.getCustomProperties() != null && !otherElement.getCustomProperties().isEmpty()) {
for (CustomProperty property : otherElement.getCustomProperties()) {
......
......@@ -19,7 +19,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Tijs Rademakers
*/
......@@ -35,7 +34,8 @@ public class UserTask extends Task {
protected List<String> candidateGroups = new ArrayList<String>();
protected List<FormProperty> formProperties = new ArrayList<FormProperty>();
protected List<ActivitiListener> taskListeners = new ArrayList<ActivitiListener>();
protected String skipExpression;
protected Map<String, Set<String>> customUserIdentityLinks = new HashMap<String, Set<String>>();
protected Map<String, Set<String>> customGroupIdentityLinks = new HashMap<String, Set<String>>();
......@@ -135,11 +135,17 @@ public class UserTask extends Task {
return customGroupIdentityLinks;
}
public void setCustomGroupIdentityLinks(
Map<String, Set<String>> customGroupIdentityLinks) {
this.customGroupIdentityLinks = customGroupIdentityLinks;
public void setCustomGroupIdentityLinks(Map<String, Set<String>> customGroupIdentityLinks) {
this.customGroupIdentityLinks = customGroupIdentityLinks;
}
public String getSkipExpression() {
return skipExpression;
}
public void setSkipExpression(String skipExpression) {
this.skipExpression = skipExpression;
}
public UserTask clone() {
UserTask clone = new UserTask();
clone.setValues(this);
......
......@@ -14,9 +14,11 @@
package org.activiti.engine.impl.bpmn.behavior;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.impl.Condition;
import org.activiti.engine.impl.bpmn.helper.SkipExpressionUtil;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
......@@ -118,12 +120,19 @@ public class BpmnActivityBehavior implements Serializable {
List<PvmTransition> outgoingTransitions = execution.getActivity().getOutgoingTransitions();
for (PvmTransition outgoingTransition : outgoingTransitions) {
if (defaultSequenceFlow == null || !outgoingTransition.getId().equals(defaultSequenceFlow)) {
Condition condition = (Condition) outgoingTransition.getProperty(BpmnParse.PROPERTYNAME_CONDITION);
if (condition == null || !checkConditions || condition.evaluate(execution)) {
transitionsToTake.add(outgoingTransition);
Expression skipExpression = outgoingTransition.getSkipExpression();
if(! SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpression)) {
if (defaultSequenceFlow == null || !outgoingTransition.getId().equals(defaultSequenceFlow)) {
Condition condition = (Condition) outgoingTransition.getProperty(BpmnParse.PROPERTYNAME_CONDITION);
if (condition == null || !checkConditions || condition.evaluate(execution)) {
transitionsToTake.add(outgoingTransition);
}
}
}
else if(SkipExpressionUtil.skipFlowElement(execution, skipExpression)){
transitionsToTake.add(outgoingTransition);
}
}
if (transitionsToTake.size() == 1) {
......
......@@ -20,6 +20,7 @@ import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.impl.bpmn.helper.ClassDelegate;
import org.activiti.engine.impl.bpmn.helper.ErrorPropagation;
import org.activiti.engine.impl.bpmn.helper.SkipExpressionUtil;
import org.activiti.engine.impl.bpmn.parser.FieldDeclaration;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.delegate.ActivityBehaviorInvocation;
......@@ -41,10 +42,12 @@ import org.activiti.engine.impl.pvm.delegate.SignallableActivityBehavior;
public class ServiceTaskDelegateExpressionActivityBehavior extends TaskActivityBehavior {
protected Expression expression;
protected Expression skipExpression;
private final List<FieldDeclaration> fieldDeclarations;
public ServiceTaskDelegateExpressionActivityBehavior(Expression expression, List<FieldDeclaration> fieldDeclarations) {
public ServiceTaskDelegateExpressionActivityBehavior(Expression expression, Expression skipExpression, List<FieldDeclaration> fieldDeclarations) {
this.expression = expression;
this.skipExpression = skipExpression;
this.fieldDeclarations = fieldDeclarations;
}
......@@ -60,27 +63,29 @@ public class ServiceTaskDelegateExpressionActivityBehavior extends TaskActivityB
public void execute(ActivityExecution execution) throws Exception {
try {
boolean isSkipExpressionEnabled = SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpression);
if (!isSkipExpressionEnabled ||
(isSkipExpressionEnabled && !SkipExpressionUtil.skipFlowElement(execution, skipExpression))) {
// Note: we can't cache the result of the expression, because the
// execution can change: eg.
// delegateExpression='${mySpringBeanFactory.randomSpringBean()}'
Object delegate = expression.getValue(execution);
ClassDelegate.applyFieldDeclaration(fieldDeclarations, delegate);
// Note: we can't cache the result of the expression, because the
// execution can change: eg. delegateExpression='${mySpringBeanFactory.randomSpringBean()}'
Object delegate = expression.getValue(execution);
ClassDelegate.applyFieldDeclaration(fieldDeclarations, delegate);
if (delegate instanceof ActivityBehavior) {
Context.getProcessEngineConfiguration().getDelegateInterceptor()
.handleInvocation(new ActivityBehaviorInvocation((ActivityBehavior) delegate, execution));
if (delegate instanceof ActivityBehavior) {
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new ActivityBehaviorInvocation((ActivityBehavior) delegate, execution));
} else if (delegate instanceof JavaDelegate) {
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(new JavaDelegateInvocation((JavaDelegate) delegate, execution));
leave(execution);
} else if (delegate instanceof JavaDelegate) {
Context.getProcessEngineConfiguration().getDelegateInterceptor().handleInvocation(new JavaDelegateInvocation((JavaDelegate) delegate, execution));
leave(execution);
} else {
throw new ActivitiIllegalArgumentException("Delegate expression " + expression + " did neither resolve to an implementation of "
+ ActivityBehavior.class + " nor " + JavaDelegate.class);
}
} else {
throw new ActivitiIllegalArgumentException("Delegate expression " + expression
+ " did neither resolve to an implementation of " + ActivityBehavior.class
+ " nor " + JavaDelegate.class);
leave(execution);
}
} catch (Exception exc) {
......
......@@ -13,15 +13,16 @@
package org.activiti.engine.impl.bpmn.behavior;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.delegate.BpmnError;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.impl.bpmn.helper.ErrorPropagation;
import org.activiti.engine.impl.bpmn.helper.SkipExpressionUtil;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
/**
* ActivityBehavior that evaluates an expression when executed. Optionally, it sets the result
* of the expression as a variable on the execution.
* ActivityBehavior that evaluates an expression when executed. Optionally, it
* sets the result of the expression as a variable on the execution.
*
* @author Tom Baeyens
* @author Christian Stettler
......@@ -32,21 +33,28 @@ import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
public class ServiceTaskExpressionActivityBehavior extends TaskActivityBehavior {
protected Expression expression;
protected Expression skipExpression;
protected String resultVariable;
public ServiceTaskExpressionActivityBehavior(Expression expression, String resultVariable) {
public ServiceTaskExpressionActivityBehavior(Expression expression, Expression skipExpression, String resultVariable) {
this.expression = expression;
this.skipExpression = skipExpression;
this.resultVariable = resultVariable;
}
public void execute(ActivityExecution execution) throws Exception {
Object value = null;
try {
value = expression.getValue(execution);
if (resultVariable != null) {
execution.setVariable(resultVariable, value);
}
leave(execution);
Object value = null;
try {
boolean isSkipExpressionEnabled = SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpression);
if (!isSkipExpressionEnabled ||
(isSkipExpressionEnabled && !SkipExpressionUtil.skipFlowElement(execution, skipExpression))) {
value = expression.getValue(execution);
if (resultVariable != null) {
execution.setVariable(resultVariable, value);
}
}
leave(execution);
} catch (Exception exc) {
Throwable cause = exc;
......
......@@ -26,6 +26,7 @@ import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.impl.bpmn.helper.SkipExpressionUtil;
import org.activiti.engine.impl.calendar.BusinessCalendar;
import org.activiti.engine.impl.calendar.DueDateBusinessCalendar;
import org.activiti.engine.impl.context.Context;
......@@ -131,6 +132,12 @@ public class UserTaskActivityBehavior extends TaskActivityBehavior {
}
task.fireEvent(TaskListener.EVENTNAME_CREATE);
Expression skipExpression = taskDefinition.getSkipExpression();
if (SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpression) &&
SkipExpressionUtil.skipFlowElement(execution, skipExpression)) {
leave(execution);
}
}
public void signal(ActivityExecution execution, String signalName, Object signalData) throws Exception {
......
......@@ -22,6 +22,7 @@ import org.activiti.engine.ActivitiException;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.delegate.BpmnError;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.JavaDelegate;
......@@ -54,14 +55,16 @@ public class ClassDelegate extends AbstractBpmnActivityBehavior implements TaskL
protected ExecutionListener executionListenerInstance;
protected TaskListener taskListenerInstance;
protected ActivityBehavior activityBehaviorInstance;
public ClassDelegate(String className, List<FieldDeclaration> fieldDeclarations) {
protected Expression skipExpression;
public ClassDelegate(String className, List<FieldDeclaration> fieldDeclarations, Expression skipExpression) {
this.className = className;
this.fieldDeclarations = fieldDeclarations;
this.skipExpression = skipExpression;
}
public ClassDelegate(Class<?> clazz, List<FieldDeclaration> fieldDeclarations) {
this(clazz.getName(), fieldDeclarations);
public ClassDelegate(Class< ? > clazz, List<FieldDeclaration> fieldDeclarations, Expression skipExpression) {
this(clazz.getName(), fieldDeclarations, skipExpression);
}
// Execution listener
......@@ -110,13 +113,17 @@ public class ClassDelegate extends AbstractBpmnActivityBehavior implements TaskL
// Activity Behavior
public void execute(ActivityExecution execution) throws Exception {
if (activityBehaviorInstance == null) {
activityBehaviorInstance = getActivityBehaviorInstance(execution);
}
try {
activityBehaviorInstance.execute(execution);
} catch (BpmnError error) {
ErrorPropagation.propagateError(error, execution);
boolean isSkipExpressionEnabled = SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpression);
if (!isSkipExpressionEnabled ||
(isSkipExpressionEnabled && !SkipExpressionUtil.skipFlowElement(execution, skipExpression))) {
if (activityBehaviorInstance == null) {
activityBehaviorInstance = getActivityBehaviorInstance(execution);
}
try {
activityBehaviorInstance.execute(execution);
} catch (BpmnError error) {
ErrorPropagation.propagateError(error, execution);
}
}
}
......
package org.activiti.engine.impl.bpmn.helper;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
public class SkipExpressionUtil {
public static boolean isSkipExpressionEnabled(ActivityExecution execution, Expression skipExpression)
{
if(null == skipExpression)
{
return false;
}
final String skipExpressionEnabledVariable = "_ACTIVITI_SKIP_EXPRESSION_ENABLED";
Object isSkipExpressionEnabled = execution.getVariable(skipExpressionEnabledVariable);
if(null == isSkipExpressionEnabled)
{
return false;
}
else if(isSkipExpressionEnabled instanceof Boolean)
{
return ((Boolean)isSkipExpressionEnabled).booleanValue();
}
else
{
throw new ActivitiIllegalArgumentException(skipExpressionEnabledVariable + " variable does not resolve to a boolean. " + isSkipExpressionEnabled);
}
}
public static boolean skipFlowElement(ActivityExecution execution, Expression skipExpression)
{
Object value = skipExpression.getValue(execution);
if(value instanceof Boolean)
{
return ((Boolean)value).booleanValue();
}
else
{
throw new ActivitiIllegalArgumentException("Skip expression does not resolve to a boolean: " + skipExpression.getExpressionText());
}
}
}
......@@ -89,9 +89,9 @@ import org.activiti.engine.impl.task.TaskDefinition;
import org.apache.commons.lang3.StringUtils;
/**
* Default implementation of the {@link ActivityBehaviorFactory}.
* Used when no custom {@link ActivityBehaviorFactory} is injected on
* the {@link ProcessEngineConfigurationImpl}.
* Default implementation of the {@link ActivityBehaviorFactory}. Used when no
* custom {@link ActivityBehaviorFactory} is injected on the
* {@link ProcessEngineConfigurationImpl}.
*
* @author Joram Barrez
*/
......@@ -128,17 +128,43 @@ public class DefaultActivityBehaviorFactory extends AbstractBehaviorFactory impl
// Service task
public ClassDelegate createClassDelegateServiceTask(ServiceTask serviceTask) {
return new ClassDelegate(serviceTask.getImplementation(), createFieldDeclarations(serviceTask.getFieldExtensions()));
Expression skipExpression;
if(StringUtils.isNotEmpty(serviceTask.getSkipExpression()))
{
skipExpression = expressionManager.createExpression(serviceTask.getSkipExpression());
}
else
{
skipExpression = null;
}
return new ClassDelegate(serviceTask.getImplementation(), createFieldDeclarations(serviceTask.getFieldExtensions()), skipExpression);
}
public ServiceTaskDelegateExpressionActivityBehavior createServiceTaskDelegateExpressionActivityBehavior(ServiceTask serviceTask) {
Expression delegateExpression = expressionManager.createExpression(serviceTask.getImplementation());
return new ServiceTaskDelegateExpressionActivityBehavior(delegateExpression, createFieldDeclarations(serviceTask.getFieldExtensions()));
Expression skipExpression;
if(StringUtils.isNotEmpty(serviceTask.getSkipExpression()))
{
skipExpression = expressionManager.createExpression(serviceTask.getSkipExpression());
}
else
{
skipExpression = null;
}
return new ServiceTaskDelegateExpressionActivityBehavior(delegateExpression, skipExpression, createFieldDeclarations(serviceTask.getFieldExtensions()));
}
public ServiceTaskExpressionActivityBehavior createServiceTaskExpressionActivityBehavior(ServiceTask serviceTask) {
Expression expression = expressionManager.createExpression(serviceTask.getImplementation());
return new ServiceTaskExpressionActivityBehavior(expression, serviceTask.getResultVariableName());
Expression skipExpression;
if (StringUtils.isNotEmpty(serviceTask.getSkipExpression())) {
skipExpression = expressionManager.createExpression(serviceTask.getSkipExpression());
}
else
{
skipExpression = null;
}
return new ServiceTaskExpressionActivityBehavior(expression, skipExpression, serviceTask.getResultVariableName());
}
public WebServiceActivityBehavior createWebServiceActivityBehavior(ServiceTask serviceTask) {
......
......@@ -65,7 +65,7 @@ public class DefaultListenerFactory extends AbstractBehaviorFactory implements L
}
public TaskListener createClassDelegateTaskListener(ActivitiListener activitiListener) {
return new ClassDelegate(activitiListener.getImplementation(), createFieldDeclarations(activitiListener.getFieldExtensions()));
return new ClassDelegate(activitiListener.getImplementation(), createFieldDeclarations(activitiListener.getFieldExtensions()), null);
}
public TaskListener createExpressionTaskListener(ActivitiListener activitiListener) {
......@@ -78,7 +78,7 @@ public class DefaultListenerFactory extends AbstractBehaviorFactory implements L
}
public ExecutionListener createClassDelegateExecutionListener(ActivitiListener activitiListener) {
return new ClassDelegate(activitiListener.getImplementation(), createFieldDeclarations(activitiListener.getFieldExtensions()));
return new ClassDelegate(activitiListener.getImplementation(), createFieldDeclarations(activitiListener.getFieldExtensions()), null);
}
public ExecutionListener createExpressionExecutionListener(ActivitiListener activitiListener) {
......
......@@ -14,8 +14,10 @@ package org.activiti.engine.impl.bpmn.parser.handler;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.impl.Condition;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.el.UelExpressionCondition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
......@@ -41,7 +43,18 @@ public class SequenceFlowParseHandler extends AbstractBpmnParseHandler<SequenceF
ActivityImpl sourceActivity = scope.findActivity(sequenceFlow.getSourceRef());
ActivityImpl destinationActivity = scope.findActivity(sequenceFlow.getTargetRef());
TransitionImpl transition = sourceActivity.createOutgoingTransition(sequenceFlow.getId());
Expression skipExpression;
if(StringUtils.isNotEmpty(sequenceFlow.getSkipExpression()))
{
ExpressionManager expressionManager = bpmnParse.getExpressionManager();
skipExpression = expressionManager.createExpression(sequenceFlow.getSkipExpression());
}
else
{
skipExpression = null;
}
TransitionImpl transition = sourceActivity.createOutgoingTransition(sequenceFlow.getId(), skipExpression);
bpmnParse.getSequenceFlows().put(sequenceFlow.getId(), transition);
transition.setProperty("name", sequenceFlow.getName());
transition.setProperty("documentation", sequenceFlow.getDocumentation());
......
......@@ -129,6 +129,10 @@ public class UserTaskParseHandler extends AbstractActivityBpmnParseHandler<UserT
taskDefinition.addCustomGroupIdentityLinkExpression(customGroupIdentityLinkType, groupIdentityLinkExpression);
}
if (StringUtils.isNotEmpty(userTask.getSkipExpression())) {
taskDefinition.setSkipExpression(expressionManager.createExpression(userTask.getSkipExpression()));
}
return taskDefinition;
}
......
......@@ -81,7 +81,7 @@ public class ProcessDefinitionBuilder {
throw new PvmException("destinationActivityId is null");
}
ActivityImpl activity = getActivity();
transition = activity.createOutgoingTransition(transitionId);
transition = activity.createOutgoingTransition(transitionId, null);
unresolvedTransitions.add(new Object[]{transition, destinationActivityId});
processElement = transition;
return this;
......
......@@ -13,6 +13,8 @@
package org.activiti.engine.impl.pvm;
import org.activiti.engine.delegate.Expression;
/**
......@@ -23,4 +25,6 @@ public interface PvmTransition extends PvmProcessElement {
PvmActivity getSource();
PvmActivity getDestination();
Expression getSkipExpression();
}
......@@ -18,6 +18,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmException;
import org.activiti.engine.impl.pvm.PvmTransition;
......@@ -52,7 +53,7 @@ public class ActivityImpl extends ScopeImpl implements PvmActivity, HasDIBounds
}
public TransitionImpl createOutgoingTransition() {
return createOutgoingTransition(null);
return createOutgoingTransition(null, null);
}
public String getFailedJobRetryTimeCycleValue() {
return failedJobRetryTimeCycleValue;
......@@ -61,8 +62,8 @@ public class ActivityImpl extends ScopeImpl implements PvmActivity, HasDIBounds
this.failedJobRetryTimeCycleValue = failedJobRetryTimeCycleValue;
}
public TransitionImpl createOutgoingTransition(String transitionId) {
TransitionImpl transition = new TransitionImpl(transitionId, processDefinition);
public TransitionImpl createOutgoingTransition(String transitionId, Expression skipExpression) {
TransitionImpl transition = new TransitionImpl(transitionId, skipExpression, processDefinition);
transition.setSource(this);
outgoingTransitions.add(transition);
......
......@@ -18,6 +18,7 @@ import java.util.Collections;
import java.util.List;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.impl.pvm.PvmTransition;
......@@ -31,12 +32,14 @@ public class TransitionImpl extends ProcessElementImpl implements PvmTransition
protected ActivityImpl source;
protected ActivityImpl destination;
protected List<ExecutionListener> executionListeners;
protected Expression skipExpression;
/** Graphical information: a list of waypoints: x1, y1, x2, y2, x3, y3, .. */
protected List<Integer> waypoints = new ArrayList<Integer>();
public TransitionImpl(String id, ProcessDefinitionImpl processDefinition) {
public TransitionImpl(String id, Expression skipExpression, ProcessDefinitionImpl processDefinition) {
super(id, processDefinition);
this.skipExpression = skipExpression;
}
public ActivityImpl getSource() {
......@@ -88,5 +91,12 @@ public class TransitionImpl extends ProcessElementImpl implements PvmTransition
public void setWaypoints(List<Integer> waypoints) {
this.waypoints = waypoints;
}
public Expression getSkipExpression() {
return skipExpression;
}
public void setSkipExpression(Expression skipExpression) {
this.skipExpression = skipExpression;
}
}
......@@ -46,7 +46,8 @@ public class TaskDefinition implements Serializable {
protected Expression priorityExpression;
protected Expression categoryExpression;
protected Map<String, Set<Expression>> customUserIdentityLinkExpressions = new HashMap<String, Set<Expression>>();
protected Map<String, Set<Expression>> customGroupIdentityLinkExpressions = new HashMap<String, Set<Expression>>();
protected Map<String, Set<Expression>> customGroupIdentityLinkExpressions = new HashMap<String, Set<Expression>>();
protected Expression skipExpression;
// form fields
protected TaskFormHandler taskFormHandler;
......@@ -204,4 +205,12 @@ public class TaskDefinition implements Serializable {
}
}
public Expression getSkipExpression() {
return skipExpression;
}
public void setSkipExpression(Expression skipExpression) {
this.skipExpression = skipExpression;
}
}
......@@ -165,7 +165,7 @@ public class TestActivityBehaviorFactory extends AbstractBehaviorFactory impleme
} else if (serviceTask.getImplementation() != null && mockedClassDelegatesMapping.containsKey(serviceTask.getImplementation())) {
return new ClassDelegate(mockedClassDelegatesMapping.get(serviceTask.getImplementation()),
createFieldDeclarations(serviceTask.getFieldExtensions()));
createFieldDeclarations(serviceTask.getFieldExtensions()), null);
}
......@@ -176,7 +176,7 @@ public class TestActivityBehaviorFactory extends AbstractBehaviorFactory impleme
List<FieldDeclaration> fieldDeclarations = new ArrayList<FieldDeclaration>();
fieldDeclarations.add(new FieldDeclaration("name",
Expression.class.getName(), new FixedValue(serviceTask.getImplementation())));
return new ClassDelegate(NoOpServiceTask.class, fieldDeclarations);
return new ClassDelegate(NoOpServiceTask.class, fieldDeclarations, null);
}
@Override
......
......@@ -13,6 +13,7 @@
package org.activiti.engine.test.bpmn.sequenceflow;
import java.util.HashMap;
import java.util.Map;
import org.activiti.engine.impl.test.PluggableActivitiTestCase;
......@@ -39,4 +40,21 @@ public class ConditionalSequenceFlowTest extends PluggableActivitiTestCase {
assertEquals("task right", task.getName());
}
@Deployment
public void testSkipExpression() {
Map<String, Object> variables = new HashMap<String,Object>();
variables.put("input", "right");
variables.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", true);
variables.put("skipLeft", true);
variables.put("skipRight", false);
ProcessInstance pi = runtimeService.startProcessInstanceByKey("testSkipExpression", variables);
Task task = taskService
.createTaskQuery()
.processInstanceId(pi.getId())
.singleResult();
assertEquals("task left", task.getName());
}
}
\ No newline at end of file
......@@ -20,6 +20,29 @@ public class ExpressionServiceTaskTest extends PluggableActivitiTestCase {
assertEquals("ok", runtimeService.getVariable(pi.getId(), "result"));
}
@Deployment
public void testSetServiceResultToProcessVariablesWithSkipExpression() {
Map<String,Object> variables = new HashMap<String, Object>();
variables.put("bean", new ValueBean("ok"));
variables.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", true);
variables.put("skip", false);
ProcessInstance pi = runtimeService.startProcessInstanceByKey("setServiceResultToProcessVariablesWithSkipExpression", variables);
assertEquals("ok", runtimeService.getVariable(pi.getId(), "result"));
Map<String,Object> variables2 = new HashMap<String, Object>();
variables2.put("bean", new ValueBean("ok"));
variables2.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", true);
variables2.put("skip", true);
ProcessInstance pi2 = runtimeService.startProcessInstanceByKey("setServiceResultToProcessVariablesWithSkipExpression", variables2);
assertEquals(null, runtimeService.getVariable(pi2.getId(), "result"));
Map<String,Object> variables3 = new HashMap<String, Object>();
variables3.put("bean", new ValueBean("ok"));
variables3.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", true);
ProcessInstance pi3 = runtimeService.startProcessInstanceByKey("setServiceResultToProcessVariablesWithSkipExpression", variables2);
assertEquals(null, runtimeService.getVariable(pi3.getId(), "result"));
}
@Deployment
public void testBackwardsCompatibleExpression() {
Map<String,Object> variables = new HashMap<String, Object>();
......
......@@ -71,6 +71,40 @@ public class JavaServiceTaskTest extends PluggableActivitiTestCase {
assertEquals("elam :si redneg ruoY", runtimeService.getVariable(execution.getId(), "var1"));
}
@Deployment
public void testExpressionFieldInjectionWithSkipExpression() {
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("name", "kermit");
vars.put("gender", "male");
vars.put("genderBean", new GenderBean());
vars.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", true);
vars.put("skip", false);
ProcessInstance pi = runtimeService.startProcessInstanceByKey("expressionFieldInjectionWithSkipExpression", vars);
Execution execution = runtimeService.createExecutionQuery()
.processInstanceId(pi.getId())
.activityId("waitState")
.singleResult();
assertEquals("timrek .rM olleH", runtimeService.getVariable(execution.getId(), "var2"));
assertEquals("elam :si redneg ruoY", runtimeService.getVariable(execution.getId(), "var1"));
Map<String, Object> vars2 = new HashMap<String, Object>();
vars2.put("name", "kermit");
vars2.put("gender", "male");
vars2.put("genderBean", new GenderBean());
vars2.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", true);
vars2.put("skip", true);
ProcessInstance pi2 = runtimeService.startProcessInstanceByKey("expressionFieldInjectionWithSkipExpression", vars2);
Execution execution2 = runtimeService.createExecutionQuery()
.processInstanceId(pi2.getId())
.activityId("waitState")
.singleResult();
assertEquals(null, execution2);
}
@Deployment
public void testUnexistingClassDelegation() {
try {
......
......@@ -22,4 +22,24 @@ public class MethodExpressionServiceTaskTest extends PluggableActivitiTestCase {
assertEquals("ok", runtimeService.getVariable(pi.getId(), "result"));
}
@Deployment
public void testSetServiceResultToProcessVariablesWithSkipExpression() {
Map<String,Object> variables = new HashMap<String, Object>();
variables.put("okReturningService", new OkReturningService());
variables.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", false);
ProcessInstance pi = runtimeService.startProcessInstanceByKey("setServiceResultToProcessVariablesWithSkipExpression", variables);
assertEquals("ok", runtimeService.getVariable(pi.getId(), "result"));
Map<String,Object> variables2 = new HashMap<String, Object>();
variables2.put("okReturningService", new OkReturningService());
variables2.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", true);
variables2.put("skip", true);
ProcessInstance pi2 = runtimeService.startProcessInstanceByKey("setServiceResultToProcessVariablesWithSkipExpression", variables2);
assertEquals(null, runtimeService.getVariable(pi2.getId(), "result"));
}
}
\ No newline at end of file
package org.activiti.examples.bpmn.usertask;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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;
public class SkipExpressionUserTaskTest extends PluggableActivitiTestCase {
@Deployment
public void test() {
ProcessInstance pi = runtimeService.startProcessInstanceByKey("skipExpressionUserTask");
List<Task> tasks = taskService.createTaskQuery().list();
assertEquals(1, tasks.size());
taskService.complete(tasks.get(0).getId());
assertEquals(0, taskService.createTaskQuery().list().size());
Map<String, Object> variables2 = new HashMap<String, Object>();
variables2.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", true);
variables2.put("skip", false);
ProcessInstance pi2 = runtimeService.startProcessInstanceByKey("skipExpressionUserTask", variables2);
List<Task> tasks2 = taskService.createTaskQuery().list();
assertEquals(1, tasks2.size());
taskService.complete(tasks2.get(0).getId());
assertEquals(0, taskService.createTaskQuery().list().size());
Map<String, Object> variables3 = new HashMap<String, Object>();
variables3.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", true);
variables3.put("skip", true);
ProcessInstance pi3 = runtimeService.startProcessInstanceByKey("skipExpressionUserTask", variables3);
List<Task> tasks3 = taskService.createTaskQuery().list();
assertEquals(0, tasks3.size());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="testSkipExpression">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="task1" activiti:skipExpression="${skipLeft}">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[${input == 'left'}]]>
</conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow2" sourceRef="theStart" targetRef="task2" activiti:skipExpression="${skipRight}">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[${input == 'right'}]]>
</conditionExpression>
</sequenceFlow>
<userTask id="task1" name="task left" />
<userTask id="task2" name="task right" />
</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="setServiceResultToProcessVariablesWithSkipExpression">
<startEvent id="theStart"/>
<sequenceFlow sourceRef="theStart"
targetRef="valueExpressionServiceWithResultVariableNameSet"/>
<serviceTask id="valueExpressionServiceWithResultVariableNameSet"
activiti:resultVariable="result"
activiti:expression="#{bean.value}"
activiti:skipExpression="${execution.getVariable('skip')}"/>
<sequenceFlow sourceRef="valueExpressionServiceWithResultVariableNameSet"
targetRef="valueExpressionServiceWithoutResultVariableNameSet"/>
<serviceTask id="valueExpressionServiceWithoutResultVariableNameSet"
activiti:expression="#{bean.value}"/>
<sequenceFlow sourceRef="valueExpressionServiceWithoutResultVariableNameSet"
targetRef="waitState"/>
<userTask id="waitState"/>
<sequenceFlow sourceRef="waitState" targetRef="theEnd"/>
<endEvent id="theEnd"/>
</process>
</definitions>
<?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="expressionFieldInjectionWithSkipExpression">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="javaService" />
<serviceTask id="javaService"
name="Java service invocation"
activiti:class="org.activiti.examples.bpmn.servicetask.ReverseStringsFieldInjected"
activiti:skipExpression="${execution.getVariable('skip')}">
<extensionElements>
<activiti:field name="text1">
<activiti:expression>${genderBean.getGenderString(gender)}</activiti:expression>
</activiti:field>
<activiti:field name="text2">
<activiti:expression>Hello ${gender == 'male' ? 'Mr.' : 'Mrs.'} ${name}</activiti:expression>
</activiti:field>
</extensionElements>
</serviceTask>
<sequenceFlow id="flow2" sourceRef="javaService" targetRef="waitState" />
<receiveTask id="waitState" />
<sequenceFlow id="flow3" sourceRef="waitState" 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="setServiceResultToProcessVariablesWithSkipExpression">
<startEvent id="theStart"/>
<sequenceFlow sourceRef="theStart"
targetRef="methodExpressionServiceWithResultVariableNameSet"/>
<serviceTask id="methodExpressionServiceWithResultVariableNameSet"
activiti:resultVariable="result"
activiti:expression="#{okReturningService.invoke()}"
activiti:skipExpression="${skip}"/>
<sequenceFlow sourceRef="methodExpressionServiceWithResultVariableNameSet"
targetRef="methodExpressionServiceWithoutResultVariableNameSet"/>
<serviceTask id="methodExpressionServiceWithoutResultVariableNameSet"
activiti:expression="#{okReturningService.invoke()}"/>
<sequenceFlow sourceRef="methodExpressionServiceWithoutResultVariableNameSet"
targetRef="waitState"/>
<userTask id="waitState"/>
<sequenceFlow sourceRef="waitState" targetRef="theEnd"/>
<endEvent id="theEnd"/>
</process>
</definitions>
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="skipExpressionUserTask">
<startEvent id="theStart" name="Start Event"/>
<sequenceFlow sourceRef="theStart" targetRef="userTask1" />
<userTask id="userTask1" name="Task1" activiti:skipExpression="${execution.getVariable('skip')}"/>
<sequenceFlow sourceRef="userTask1" targetRef="theEnd" />
<endEvent id="theEnd" name="End Event"/>
</process>
</definitions>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册