Skip to content

Commit 3c283fb

Browse files
committed
Add method on planItemInstanceEntityManager to retrieve plan item instances by type(s) and state(s) which also checks the cache
1 parent 8e25a92 commit 3c283fb

File tree

6 files changed

+144
-0
lines changed

6 files changed

+144
-0
lines changed

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/PlanItemInstanceEntityManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ public interface PlanItemInstanceEntityManager extends EntityManager<PlanItemIns
5050

5151
List<PlanItemInstanceEntity> findByStageInstanceIdAndPlanItemId(String stageInstanceId, String planItemId);
5252

53+
List<PlanItemInstanceEntity> findByCaseInstanceIdAndTypeAndState(String caseInstanceId, List<String> planItemDefinitionTypes,
54+
List<String> states, boolean ended);
55+
5356
PlanItemInstanceEntity updateHumanTaskPlanItemInstanceAssignee(TaskEntity taskEntity, String assignee);
5457

5558
PlanItemInstanceEntity updateHumanTaskPlanItemInstanceCompletedBy(TaskEntity taskEntity, String assignee);

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/PlanItemInstanceEntityManagerImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,12 @@ public List<PlanItemInstanceEntity> findByStageInstanceIdAndPlanItemId(String st
426426
return dataManager.findByStageInstanceIdAndPlanItemId(stageInstanceId, planItemId);
427427
}
428428

429+
@Override
430+
public List<PlanItemInstanceEntity> findByCaseInstanceIdAndTypeAndState(String caseInstanceId, List<String> planItemDefinitionTypes,
431+
List<String> states, boolean ended) {
432+
return dataManager.findByCaseInstanceIdAndTypeAndState(caseInstanceId, planItemDefinitionTypes, states, ended);
433+
}
434+
429435
@Override
430436
public PlanItemInstanceEntity updateHumanTaskPlanItemInstanceAssignee(TaskEntity taskEntity, String assignee) {
431437
PlanItemInstanceEntity planItemInstanceEntity = null;

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/data/PlanItemInstanceDataManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ public interface PlanItemInstanceDataManager extends DataManager<PlanItemInstanc
3232

3333
List<PlanItemInstanceEntity> findByStageInstanceIdAndPlanItemId(String stageInstanceId, String planItemId);
3434

35+
List<PlanItemInstanceEntity> findByCaseInstanceIdAndTypeAndState(String caseInstanceId, List<String> planItemDefinitionTypes,
36+
List<String> states, boolean ended);
37+
3538
List<PlanItemInstance> findByCriteria(PlanItemInstanceQueryImpl planItemInstanceQuery);
3639

3740
List<PlanItemInstance> findWithVariablesByCriteria(PlanItemInstanceQueryImpl planItemInstanceQuery);

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/data/impl/MybatisPlanItemInstanceDataManagerImpl.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ public class MybatisPlanItemInstanceDataManagerImpl extends AbstractCmmnDataMana
4141
protected PlanItemInstanceByStageInstanceIdAndPlanItemIdCachedEntityMatcher planItemInstanceByStageInstanceIdAndPlanItemIdCachedEntityMatcher =
4242
new PlanItemInstanceByStageInstanceIdAndPlanItemIdCachedEntityMatcher();
4343

44+
protected PlanItemInstanceByCaseInstanceIdAndTypeAndStateCachedEntityMatcher planItemInstanceByCaseInstanceIdAndTypeAndStateCachedEntityMatcher =
45+
new PlanItemInstanceByCaseInstanceIdAndTypeAndStateCachedEntityMatcher();
46+
4447
protected PlanItemInstanceByStagePlanItemInstanceIdCachedEntityMatcher planItemInstanceByStagePlanItemInstanceIdCachedEntityMatcher =
4548
new PlanItemInstanceByStagePlanItemInstanceIdCachedEntityMatcher();
4649

@@ -107,6 +110,18 @@ public List<PlanItemInstanceEntity> findByStageInstanceIdAndPlanItemId(String st
107110
return getList("selectPlanItemInstancesByStageInstanceIdAndPlanItemId", params, planItemInstanceByStageInstanceIdAndPlanItemIdCachedEntityMatcher);
108111
}
109112

113+
@Override
114+
public List<PlanItemInstanceEntity> findByCaseInstanceIdAndTypeAndState(String caseInstanceId, List<String> planItemDefinitionTypes,
115+
List<String> states, boolean ended) {
116+
Map<String, Object> params = new HashMap<>();
117+
params.put("caseInstanceId", caseInstanceId);
118+
params.put("planItemDefinitionTypes", planItemDefinitionTypes);
119+
params.put("states", states);
120+
params.put("ended", ended);
121+
return getList("selectPlanItemInstancesByCaseInstanceIdAndTypeAndState", params,
122+
planItemInstanceByCaseInstanceIdAndTypeAndStateCachedEntityMatcher);
123+
}
124+
110125
@Override
111126
public long countByCriteria(PlanItemInstanceQueryImpl planItemInstanceQuery) {
112127
setSafeInValueLists(planItemInstanceQuery);
@@ -191,6 +206,25 @@ public boolean isRetained(PlanItemInstanceEntity entity, Object param) {
191206
}
192207

193208
}
209+
210+
public static class PlanItemInstanceByCaseInstanceIdAndTypeAndStateCachedEntityMatcher extends CachedEntityMatcherAdapter<PlanItemInstanceEntity> {
211+
212+
@Override
213+
@SuppressWarnings("unchecked")
214+
public boolean isRetained(PlanItemInstanceEntity entity, Object param) {
215+
Map<String, Object> map = (Map<String, Object>) param;
216+
String caseInstanceId = (String) map.get("caseInstanceId");
217+
List<String> planItemDefinitionTypes = (List<String>) map.get("planItemDefinitionTypes");
218+
List<String> states = (List<String>) map.get("states");
219+
boolean ended = (boolean) map.get("ended");
220+
221+
return caseInstanceId.equals(entity.getCaseInstanceId())
222+
&& planItemDefinitionTypes.contains(entity.getPlanItemDefinitionType())
223+
&& states.contains(entity.getState())
224+
&& (ended ? entity.getEndedTime() != null : entity.getEndedTime() == null);
225+
}
226+
227+
}
194228

195229
protected void setSafeInValueLists(PlanItemInstanceQueryImpl planItemInstanceQuery) {
196230
if (planItemInstanceQuery.getInvolvedGroups() != null) {

modules/flowable-cmmn-engine/src/main/resources/org/flowable/cmmn/db/mapping/entity/PlanItemInstance.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,19 @@
369369
where STAGE_INST_ID_ = #{parameter, jdbcType=VARCHAR}
370370
</select>
371371

372+
<select id="selectPlanItemInstancesByCaseInstanceIdAndTypeAndState" parameterType="org.flowable.common.engine.impl.db.ListQueryParameterObject" resultMap="planItemInstanceResultMap">
373+
select * from ${prefix}ACT_CMMN_RU_PLAN_ITEM_INST RES
374+
where CASE_INST_ID_ = #{parameter.caseInstanceId, jdbcType=VARCHAR}
375+
and ITEM_DEFINITION_TYPE_ in <foreach item="planItemDefinitionType" index="index" collection="parameter.planItemDefinitionTypes" open="(" separator="," close=")">#{planItemDefinitionType, jdbcType=VARCHAR}</foreach>
376+
and STATE_ in <foreach item="state" index="index" collection="parameter.states" open="(" separator="," close=")">#{state, jdbcType=VARCHAR}</foreach>
377+
<if test="parameter.ended">
378+
and ENDED_TIME_ is not null
379+
</if>
380+
<if test="!parameter.ended">
381+
and ENDED_TIME_ is null
382+
</if>
383+
</select>
384+
372385
<select id="selectPlanItemInstancesByQueryCriteria" parameterType="org.flowable.cmmn.engine.impl.runtime.PlanItemInstanceQueryImpl" resultMap="planItemInstanceResultMap">
373386
<if test="needsPaging">${limitBefore}</if>
374387
SELECT RES.* <if test="needsPaging">${limitBetween}</if>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/* Licensed under the Apache License, Version 2.0 (the "License");
2+
* you may not use this file except in compliance with the License.
3+
* You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*/
13+
package org.flowable.cmmn.test.runtime;
14+
15+
import static org.assertj.core.api.Assertions.assertThat;
16+
import static org.assertj.core.api.Assertions.entry;
17+
import static org.assertj.core.api.Assertions.tuple;
18+
import static org.flowable.cmmn.api.runtime.PlanItemInstanceState.ACTIVE;
19+
20+
import java.util.ArrayList;
21+
import java.util.Arrays;
22+
import java.util.Date;
23+
import java.util.List;
24+
25+
import org.flowable.cmmn.api.history.HistoricPlanItemInstance;
26+
import org.flowable.cmmn.api.runtime.CaseInstance;
27+
import org.flowable.cmmn.api.runtime.PlanItemDefinitionType;
28+
import org.flowable.cmmn.api.runtime.PlanItemInstance;
29+
import org.flowable.cmmn.api.runtime.PlanItemInstanceState;
30+
import org.flowable.cmmn.api.runtime.UserEventListenerInstance;
31+
import org.flowable.cmmn.engine.PlanItemLocalizationManager;
32+
import org.flowable.cmmn.engine.impl.CmmnManagementServiceImpl;
33+
import org.flowable.cmmn.engine.impl.persistence.entity.PlanItemInstanceEntity;
34+
import org.flowable.cmmn.engine.impl.util.CommandContextUtil;
35+
import org.flowable.cmmn.engine.test.CmmnDeployment;
36+
import org.flowable.cmmn.engine.test.FlowableCmmnTestCase;
37+
import org.flowable.common.engine.impl.interceptor.Command;
38+
import org.flowable.common.engine.impl.interceptor.CommandContext;
39+
import org.flowable.task.api.Task;
40+
import org.junit.Before;
41+
import org.junit.Test;
42+
43+
/**
44+
* Tests methods not directly exposed on a service
45+
*
46+
* @author Joram Barrez
47+
*/
48+
public class PlanItemInstanceEntityManagerTest extends FlowableCmmnTestCase {
49+
50+
protected String caseDefinitionId;
51+
52+
@Before
53+
public void deployCaseDefinition() {
54+
String deploymentId = addDeploymentForAutoCleanup(cmmnRepositoryService.createDeployment()
55+
.addClasspathResource("org/flowable/cmmn/test/runtime/PlanItemInstanceQueryTest.testPlanItemInstanceQuery.cmmn")
56+
.deploy());
57+
caseDefinitionId = cmmnRepositoryService.createCaseDefinitionQuery()
58+
.deploymentId(deploymentId)
59+
.caseDefinitionKey("testPlanItemInstanceQuery")
60+
.singleResult()
61+
.getId();
62+
}
63+
64+
@Test
65+
public void testFindByCaseInstanceIdAndTypeAndState() {
66+
List<String> caseInstanceIds = startInstances(3);
67+
String caseInstanceId = caseInstanceIds.get(1);
68+
69+
List<PlanItemInstanceEntity> planItemInstances = ((CmmnManagementServiceImpl) cmmnManagementService).executeCommand(
70+
commandContext -> CommandContextUtil.getPlanItemInstanceEntityManager().findByCaseInstanceIdAndTypeAndState(caseInstanceId,
71+
List.of(PlanItemDefinitionType.HUMAN_TASK), List.of(PlanItemInstanceState.ENABLED), false));
72+
73+
assertThat(planItemInstances).hasSize(1);
74+
assertThat(planItemInstances.get(0).getName()).isEqualTo("B");
75+
}
76+
77+
private List<String> startInstances(int numberOfInstances) {
78+
List<String> caseInstanceIds = new ArrayList<>();
79+
for (int i = 0; i < numberOfInstances; i++) {
80+
caseInstanceIds.add(cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testPlanItemInstanceQuery").start().getId());
81+
}
82+
return caseInstanceIds;
83+
}
84+
85+
}

0 commit comments

Comments
 (0)