All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.camunda.tasklist.store.util.TaskVariableSearchUtil Maven / Gradle / Ivy

/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
 * one or more contributor license agreements. See the NOTICE file distributed
 * with this work for additional information regarding copyright ownership.
 * Licensed under the Camunda License 1.0. You may not use this file
 * except in compliance with the Camunda License 1.0.
 */
package io.camunda.tasklist.store.util;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;

import io.camunda.tasklist.entities.FlowNodeInstanceEntity;
import io.camunda.tasklist.entities.VariableEntity;
import io.camunda.tasklist.store.VariableStore;
import io.camunda.tasklist.util.CollectionUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class TaskVariableSearchUtil {
  private static final String ABSENT_PARENT_ID = "-1";

  @Autowired private VariableStore variableStore;

  public Boolean checkIfVariablesExistInTask(
      List requests, Map variableNameAndVar) {

    // build flow node trees (for each process instance)
    final Map flowNodeTrees = buildFlowNodeTrees(requests);

    // build local variable map  (for each flow node instance)
    final List flowNodeInstanceIds =
        flowNodeTrees.values().stream()
            .flatMap(f -> f.getFlowNodeInstanceIds().stream())
            .collect(Collectors.toList());
    final Map variableMaps =
        buildVariableMaps(
            flowNodeInstanceIds,
            requests.stream()
                .map(VariableStore.GetVariablesRequest::getVarNames)
                .filter(Objects::nonNull)
                .flatMap(List::stream)
                .distinct()
                .collect(toList()),
            requests
                .get(0)
                .getFieldNames()); // we assume here that all requests has the same list of  fields

    final Map> variables =
        buildResponse(flowNodeTrees, variableMaps, requests);

    for (Map.Entry> taskEntry : variables.entrySet()) {
      final List taskVariables = taskEntry.getValue();

      for (Map.Entry variableEntry : variableNameAndVar.entrySet()) {
        final String requiredVarName = variableEntry.getKey();
        final String requiredVarValue = variableEntry.getValue();

        // Check if the variable with the required name and value exists for the current task.
        final boolean exists =
            taskVariables.stream()
                .anyMatch(
                    varEntity ->
                        requiredVarName.equals(varEntity.getName())
                            && requiredVarValue.equals(varEntity.getValue()));

        if (!exists) {
          return false; // If the required variable doesn't exist for the task, return false.
        }
      }
    }

    return true;
  }

  private Map buildFlowNodeTrees(
      List requests) {
    final List processInstanceIds =
        CollectionUtil.map(requests, VariableStore.GetVariablesRequest::getProcessInstanceId);
    // get all flow node instances for all process instance ids
    final List flowNodeInstances =
        variableStore.getFlowNodeInstances(processInstanceIds);

    final Map flowNodeTrees = new HashMap<>();
    for (FlowNodeInstanceEntity flowNodeInstance : flowNodeInstances) {
      getFlowNodeTree(flowNodeTrees, flowNodeInstance.getProcessInstanceId())
          .setParent(flowNodeInstance.getId(), flowNodeInstance.getParentFlowNodeId());
    }
    return flowNodeTrees;
  }

  private VariableStore.FlowNodeTree getFlowNodeTree(
      Map flowNodeTrees, String processInstanceId) {
    if (flowNodeTrees.get(processInstanceId) == null) {
      flowNodeTrees.put(processInstanceId, new VariableStore.FlowNodeTree());
    }
    return flowNodeTrees.get(processInstanceId);
  }

  private Map buildVariableMaps(
      List flowNodeInstanceIds, List varNames, Set fieldNames) {
    // get list of all variables
    final List variables =
        variableStore.getVariablesByFlowNodeInstanceIds(flowNodeInstanceIds, varNames, fieldNames);

    return variables.stream()
        .collect(groupingBy(VariableEntity::getScopeFlowNodeId, getVariableMapCollector()));
  }

  private Collector
      getVariableMapCollector() {
    return Collector.of(
        VariableStore.VariableMap::new,
        (map, var) -> map.put(var.getName(), var),
        (map1, map2) -> {
          map1.putAll(map2);
          return map1;
        });
  }

  private Map> buildResponse(
      final Map flowNodeTrees,
      final Map variableMaps,
      final List requests) {

    final Map> response = new HashMap<>();

    for (VariableStore.GetVariablesRequest req : requests) {
      final VariableStore.FlowNodeTree flowNodeTree = flowNodeTrees.get(req.getProcessInstanceId());

      final VariableStore.VariableMap resultingVariableMap = new VariableStore.VariableMap();

      accumulateVariables(
          resultingVariableMap, variableMaps, flowNodeTree, req.getFlowNodeInstanceId());

      response.put(
          req.getTaskId(),
          resultingVariableMap.entrySet().stream()
              .sorted(Map.Entry.comparingByKey())
              .map(e -> e.getValue())
              .collect(Collectors.toList()));
    }
    return response;
  }

  private void accumulateVariables(
      VariableStore.VariableMap resultingVariableMap,
      final Map variableMaps,
      final VariableStore.FlowNodeTree flowNodeTree,
      final String flowNodeInstanceId) {
    final VariableStore.VariableMap m = variableMaps.get(flowNodeInstanceId);
    if (m != null) {
      resultingVariableMap.putAll(m);
    }
    final String parentFlowNodeId =
        flowNodeTree != null ? flowNodeTree.getParent(flowNodeInstanceId) : null;
    if (parentFlowNodeId != null && !parentFlowNodeId.equals(ABSENT_PARENT_ID)) {
      accumulateVariables(resultingVariableMap, variableMaps, flowNodeTree, parentFlowNodeId);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy