Skip to content

Commit

Permalink
Support resolving caseInstance and planItemInstance in an task listen…
Browse files Browse the repository at this point in the history
…er expression
  • Loading branch information
filiphr committed Feb 19, 2025
1 parent bc9d662 commit 8ea2976
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
*/
package org.flowable.cmmn.engine.impl.el;

import org.apache.commons.lang3.StringUtils;
import org.flowable.cmmn.api.runtime.PlanItemInstance;
import org.flowable.cmmn.engine.impl.persistence.entity.CaseInstanceEntity;
import org.flowable.cmmn.engine.impl.persistence.entity.PlanItemInstanceEntity;
import org.flowable.cmmn.engine.impl.util.CommandContextUtil;
import org.flowable.common.engine.api.scope.ScopeTypes;
import org.flowable.common.engine.api.variable.VariableContainer;
import org.flowable.common.engine.impl.el.VariableContainerELResolver;
import org.flowable.common.engine.impl.javax.el.ELContext;
import org.flowable.task.api.TaskInfo;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;

/**
Expand All @@ -40,16 +44,30 @@ public Object getValue(ELContext context, Object base, Object property) {
context.setPropertyResolved(true);
return variableContainer;

} else if ((CASE_INSTANCE_KEY.equals(property) && variableContainer instanceof PlanItemInstanceEntity)) {
context.setPropertyResolved(true);
String caseInstanceId = ((PlanItemInstanceEntity) variableContainer).getCaseInstanceId();
return CommandContextUtil.getCaseInstanceEntityManager().findById(caseInstanceId);

} else if (PLAN_ITEM_INSTANCE_KEY.equals(property) && variableContainer instanceof CaseInstanceEntity) {
// Special case: using planItemInstance as key, but only a caseInstance available
// (Happens for example for cross boundary plan items)
context.setPropertyResolved(true);
return variableContainer;
} else if ((CASE_INSTANCE_KEY.equals(property))) {
if (variableContainer instanceof PlanItemInstance planItemInstance) {
context.setPropertyResolved(true);
String caseInstanceId = planItemInstance.getCaseInstanceId();
return CommandContextUtil.getCaseInstanceEntityManager().findById(caseInstanceId);
} else if (variableContainer instanceof TaskInfo task) {
if (StringUtils.isNotEmpty(task.getScopeId()) && ScopeTypes.CMMN.equals(task.getScopeType())) {
context.setPropertyResolved(true);
String caseInstanceId = task.getScopeId();
return CommandContextUtil.getCaseInstanceEntityManager().findById(caseInstanceId);
}
}
} else if (PLAN_ITEM_INSTANCE_KEY.equals(property)) {
if (variableContainer instanceof CaseInstanceEntity) {
// Special case: using planItemInstance as key, but only a caseInstance available
// (Happens for example for cross boundary plan items)
context.setPropertyResolved(true);
return variableContainer;
} else if (variableContainer instanceof TaskInfo task) {
if (StringUtils.isNotEmpty(task.getSubScopeId()) && ScopeTypes.CMMN.equals(task.getScopeType())) {
context.setPropertyResolved(true);
return CommandContextUtil.getPlanItemInstanceEntityManager().findById(task.getSubScopeId());
}
}

} else if (PLAN_ITEM_INSTANCES_KEY.equals(property)) {
context.setPropertyResolved(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public void testListeners() {
assertVariable(caseInstance, "classDelegateVariable", "Hello World");
assertVariable(caseInstance, "variableFromDelegateExpression", "Hello World from delegate expression");
assertVariable(caseInstance, "expressionVar", "planItemIsActive");
assertVariable(caseInstance, "expressionCaseVar", "planItemIsActive");

assertVariable(caseInstance, "stageActive",true);
assertVariable(caseInstance, "milestoneReached", true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public void testCreateEvent() {
assertVariable(caseInstance, "variableFromClassDelegate", "Hello World from class delegate");
assertVariable(caseInstance, "variableFromDelegateExpression", "Hello World from delegate expression");
assertVariable(caseInstance, "expressionVariable", "Hello World from expression");
assertVariable(caseInstance, "expressionPlanItemVariable", "Hello World from expression");
assertVariable(caseInstance, "expressionCaseVariable", "Hello World from expression");
assertVariable(caseInstance, "javascriptResult", "Hello World from JavaScript");
assertVariable(caseInstance, "javaScriptVariable", "setInJavaScript");
assertVariable(caseInstance, "groovyVar", "setInGroovy");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,20 +156,6 @@ public void testOneHumanTaskExpressionCase() {
}
}

@Test
@CmmnDeployment(resources = "org/flowable/cmmn/test/task/CmmnTaskServiceTest.testOneHumanTaskCase.cmmn")
public void testOneHumanTaskVariableScopeExpressionCase() {
CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("oneHumanTaskCase").start();
Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult();

assertThatThrownBy(() -> cmmnTaskService.complete(task.getId(), Collections.singletonMap(
"${caseInstance.name}", "newCaseName"
)
))
.isInstanceOf(FlowableException.class)
.hasMessageContaining("Error while evaluating expression: ${caseInstance.name}");
}

@Test
@CmmnDeployment(resources = "org/flowable/cmmn/test/task/CmmnTaskServiceTest.testOneHumanTaskCase.cmmn")
public void testOneHumanTaskCompleteSetCaseName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<extensionElements>
<flowable:planItemLifecycleListener sourceState="available" targetState="active" class="org.flowable.cmmn.test.listener.TestLifecycleListener"></flowable:planItemLifecycleListener>
<flowable:planItemLifecycleListener sourceState="available" targetState="active" expression="${planItemInstance.setVariable('expressionVar', 'planItemIsActive')}"></flowable:planItemLifecycleListener>
<flowable:planItemLifecycleListener sourceState="available" targetState="active" expression="${caseInstance.setVariable('expressionCaseVar', 'planItemIsActive')}"></flowable:planItemLifecycleListener>
<flowable:planItemLifecycleListener sourceState="available" targetState="active" delegateExpression="${delegateListener}"></flowable:planItemLifecycleListener>
</extensionElements>
</humanTask>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
<humanTask id="sid-36995D0E-BAB2-44F2-ADD4-FD9070AFD6CA" name="Expression">
<extensionElements>
<flowable:taskListener event="create" expression="${task.setVariable('expressionVariable', 'Hello World from expression')}"></flowable:taskListener>
<flowable:taskListener event="create" expression="${planItemInstance.setVariable('expressionPlanItemVariable', 'Hello World from expression')}"></flowable:taskListener>
<flowable:taskListener event="create" expression="${caseInstance.setVariable('expressionCaseVariable', 'Hello World from expression')}"></flowable:taskListener>
</extensionElements>
</humanTask>
<humanTask id="sid-B79A0634-B1BF-44B7-8AC5-35E9E17CC65A" name="DelegateExpression">
Expand Down

0 comments on commit 8ea2976

Please sign in to comment.