/** * Returns a list of {@link PlanItemInstanceEntity} instances for the given {@link CaseInstanceEntity}, * which have a plan item that matches any of the given plan items and which are in any state. */ public static List<PlanItemInstanceEntity> findChildPlanItemInstances(CaseInstanceEntity caseInstanceEntity, List<PlanItem> planItems) { List<String> planItemIds = planItems.stream().map(PlanItem::getId).collect(Collectors.toList()); List<PlanItemInstanceEntity> childPlanItemInstances = getAllChildPlanItemInstances(caseInstanceEntity); return childPlanItemInstances.stream() .filter(planItemInstance -> planItemIds.contains(planItemInstance.getPlanItem().getId())) .collect(Collectors.toList()); }
protected static void internalCollectPlanItemInstances(PlanItemInstanceContainer planItemInstanceContainer, List<PlanItemInstanceEntity> planItemInstances) { List<PlanItemInstanceEntity> childPlanItemInstances = planItemInstanceContainer.getChildPlanItemInstances(); if (childPlanItemInstances != null && !childPlanItemInstances.isEmpty()) { for (PlanItemInstanceEntity childPlanItemInstanceEntity : childPlanItemInstances) { planItemInstances.add(childPlanItemInstanceEntity); internalCollectPlanItemInstances(childPlanItemInstanceEntity, planItemInstances); } } }
.findNonTerminalChildPlanItemInstances(caseInstanceEntity, eventListenerPlanItem); .findChildPlanItemInstancesMap(caseInstanceEntity, dependentPlanItems); while (isOrphan && parentStage != null && !parentStage.isPlanModel()) { List<PlanItemInstanceEntity> nonTerminalStagePlanItemInstances = CaseInstanceUtil .findNonTerminalChildPlanItemInstances(caseInstanceEntity, parentStage.getPlanItem()); if (!nonTerminalStagePlanItemInstances.isEmpty()) { isOrphan = false;
List<PlanItemInstanceEntity> childPlanItemInstances = CaseInstanceUtil.findChildPlanItemInstances(caseInstanceEntity, entryDependentPlanItem); List<PlanItemInstanceEntity> potentialTerminatedPlanItemInstances = planItemInstanceEntityManager .findByCaseInstanceIdAndPlanItemId(caseInstanceEntity.getId(), entryDependentPlanItem.getId()); .findChildPlanItemInstancesMap(caseInstanceEntity, parentPlanItems); List<PlanItemInstanceEntity> parentPlanItemInstancesToActivate = new ArrayList<>();
protected List<PlanItem> gatherEventListenerDependencies(PlanItem planItem) { List<PlanItem> eventListenerDependencies = Stream.concat( planItem.getEntryDependencies().stream().filter(p -> p.getPlanItemDefinition() instanceof EventListener), planItem.getExitDependencies().stream().filter(p -> p.getPlanItemDefinition() instanceof EventListener)) .collect(Collectors.toList()); // Special case: if the current plan item is a stage, we need to also verify all event listeners // that reference a child plan item of this stage. Normally this will happen automatically, unless // the child plan item instances haven't been created yet (e.g with nested stages). // As such, we need to check all plan items for which there hasn't been a plan item instance yet. if (planItem.getPlanItemDefinition() instanceof PlanFragment && PlanItemInstanceState.isInTerminalState(planItemInstanceEntity)) { // This is only true when stopping, not when a plan item gets activated (in that case, the child plan items can still be created and no special care is needed) List<PlanItem> childPlanItemsWithDependencies = getChildPlanItemsWithDependencies((PlanFragment) planItem.getPlanItemDefinition()); CaseInstanceEntity caseInstanceEntity = CommandContextUtil .getCaseInstanceEntityManager(commandContext).findById(planItemInstanceEntity.getCaseInstanceId()); Map<String, List<PlanItemInstanceEntity>> childPlanItemInstancesMap = CaseInstanceUtil .findChildPlanItemInstancesMap(caseInstanceEntity, childPlanItemsWithDependencies); for (PlanItem childPlanItemWithDependencies : childPlanItemsWithDependencies) { if (!childPlanItemInstancesMap.containsKey(childPlanItemWithDependencies.getId())) { eventListenerDependencies.addAll(childPlanItemWithDependencies.getEntryDependencies().stream() .filter(p -> p.getPlanItemDefinition() instanceof EventListener).collect(Collectors.toList())); eventListenerDependencies.addAll(childPlanItemWithDependencies.getExitDependencies().stream() .filter(p -> p.getPlanItemDefinition() instanceof EventListener).collect(Collectors.toList())); } } } return eventListenerDependencies; }
/** * Returns a list of {@link PlanItemInstanceEntity} instances for the given {@link CaseInstanceEntity}, irregardless of the state. */ public static List<PlanItemInstanceEntity> findChildPlanItemInstances(CaseInstanceEntity caseInstanceEntity, PlanItem planItem) { return getAllChildPlanItemInstances(caseInstanceEntity).stream() .filter(planItemInstance -> planItem.getId().equals(planItemInstance.getPlanItem().getId())) .collect(Collectors.toList()); }
/** * Returns a list of {@link PlanItemInstanceEntity} instances for the given {@link CaseInstanceEntity}, without any filtering. */ public static List<PlanItemInstanceEntity> getAllChildPlanItemInstances(CaseInstanceEntity caseInstanceEntity) { if (caseInstanceEntity == null) { throw new FlowableException("Programmatic error: case instance entity is null"); } // Typically, this comes out of the cache as the child plan item instance are cached on case instance fetch List<PlanItemInstanceEntity> planItemInstances = new ArrayList<>(); internalCollectPlanItemInstances(caseInstanceEntity, planItemInstances); return planItemInstances; }
/** * Returns a list of {@link PlanItemInstanceEntity} instances for the given {@link CaseInstanceEntity}, * which have a plan item that matches the given plan item and which are non terminal. */ public static List<PlanItemInstanceEntity> findNonTerminalChildPlanItemInstances(CaseInstanceEntity caseInstanceEntity, PlanItem planItem) { List<PlanItemInstanceEntity> childPlanItemInstances = getAllChildPlanItemInstances(caseInstanceEntity); return childPlanItemInstances.stream() .filter(planItemInstance -> planItem.getId().equals(planItemInstance.getPlanItem().getId()) && !PlanItemInstanceState.isInTerminalState(planItemInstance)) .collect(Collectors.toList()); }
/** * Similar to {@link #findChildPlanItemInstances(CaseInstanceEntity, List)}, but returns a map {planItemId, List<PlanItemInstances>} */ public static Map<String, List<PlanItemInstanceEntity>> findChildPlanItemInstancesMap(CaseInstanceEntity caseInstanceEntity, List<PlanItem> planItems) { Map<String, List<PlanItemInstanceEntity>> result = new HashMap<>(); List<String> planItemIds = planItems.stream().map(PlanItem::getId).collect(Collectors.toList()); List<PlanItemInstanceEntity> childPlanItemInstances = getAllChildPlanItemInstances(caseInstanceEntity); for (PlanItemInstanceEntity childPlanItemInstance : childPlanItemInstances) { PlanItem childPlanItem = childPlanItemInstance.getPlanItem(); if (planItemIds.contains(childPlanItem.getId())) { if (!result.containsKey(childPlanItem.getId())) { result.put(childPlanItem.getId(), new ArrayList<>()); } result.get(childPlanItem.getId()).add(childPlanItemInstance); } } return result; }