content: /*
   * Copyright 2010-2025 Hyland Software, Inc. and its affiliates.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.activiti.engine.test.api.runtime;
  
  import static org.assertj.core.api.Assertions.assertThat;
  
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import org.activiti.engine.impl.persistence.entity.VariableInstance;
  import org.activiti.engine.impl.test.PluggableActivitiTestCase;
  import org.activiti.engine.runtime.Execution;
  import org.activiti.engine.runtime.ProcessInstance;
  import org.activiti.engine.task.Task;
  import org.activiti.engine.test.Deployment;
  
  /**
   */
  public class RuntimeVariablesTest extends PluggableActivitiTestCase {
  
      @Deployment
      public void testGetVariablesByExecutionIds() {
          ProcessInstance processInstance1 = runtimeService.startProcessInstanceByKey("oneTaskProcess");
          ProcessInstance processInstance2 = runtimeService.startProcessInstanceByKey("oneTaskProcess");
          Task task1 = taskService.createTaskQuery().processInstanceId(processInstance1.getId()).singleResult();
          Task task2 = taskService.createTaskQuery().processInstanceId(processInstance2.getId()).singleResult();
  
          // Task local variables
          taskService.setVariableLocal(task1.getId(), "taskVar1", "sayHello1");
          // Execution variables
          taskService.setVariable(task1.getId(), "executionVar1", "helloWorld1");
  
          // Task local variables
          taskService.setVariableLocal(task2.getId(), "taskVar2", "sayHello2");
          // Execution variables
          taskService.setVariable(task2.getId(), "executionVar2", "helloWorld2");
  
          // only 1 process
          Set<String> executionIds = new HashSet<String>();
          executionIds.add(processInstance1.getId());
          List<VariableInstance> variables = runtimeService.getVariableInstancesByExecutionIds(executionIds);
          assertThat(variables).hasSize(1);
          checkVariable(processInstance1.getId(), "executionVar1", "helloWorld1", variables);
  
          // 2 process
          executionIds = new HashSet<String>();
          executionIds.add(processInstance1.getId());
          executionIds.add(processInstance2.getId());
          variables = runtimeService.getVariableInstancesByExecutionIds(executionIds);
          assertThat(variables).hasSize(2);
          checkVariable(processInstance1.getId(), "executionVar1", "helloWorld1", variables);
          checkVariable(processInstance2.getId(), "executionVar2", "helloWorld2", variables);
      }
  
      @Deployment(
          resources = {
              "org/activiti/engine/test/api/runtime/RuntimeVariablesTest.testGetVariablesByExecutionIds.bpmn20.xml",
          }
      )
      public void testGetSerializableTypeVariable() {
          ProcessInstance processInstance1 = runtimeService.startProcessInstanceByKey("oneTaskProcess");
          Task task1 = taskService.createTaskQuery().processInstanceId(processInstance1.getId()).singleResult();
  
          StringBuilder sb = new StringBuilder("a");
          for (int i = 0; i < 4001; i++) {
              sb.append("a");
          }
          String serializableTypeVar = sb.toString();
  
          // Task variables
          taskService.setVariableLocal(task1.getId(), "taskVar1", serializableTypeVar);
  
          VariableInstance variableInstance = taskService.getVariableInstance(task1.getId(), "taskVar1");
          assertThat(variableInstance.getValue()).isEqualTo(serializableTypeVar);
  
          Map<String, VariableInstance> variableInstances = taskService.getVariableInstances(task1.getId());
          assertThat(variableInstances.get("taskVar1").getValue()).isEqualTo(serializableTypeVar);
  
          // Execution variables
          taskService.setVariable(task1.getId(), "executionVar1", serializableTypeVar);
  
          Set<String> executionIds = new HashSet<String>();
          executionIds.add(processInstance1.getId());
          List<VariableInstance> variables = runtimeService.getVariableInstancesByExecutionIds(executionIds);
          assertThat(variables.get(0).getValue()).isEqualTo(serializableTypeVar);
  
          variableInstance = runtimeService.getVariableInstance(processInstance1.getId(), "executionVar1");
          assertThat(variableInstance.getValue()).isEqualTo(serializableTypeVar);
  
          variableInstances = runtimeService.getVariableInstances(processInstance1.getId());
          assertThat(variableInstances.get("executionVar1").getValue()).isEqualTo(serializableTypeVar);
      }
  
      private void checkVariable(String executionId, String name, String value, List<VariableInstance> variables) {
          assertThat(variables)
              .filteredOn(variable -> executionId.equals(variable.getExecutionId()))
              .first()
              .satisfies(variable -> {
                  assertThat(variable.getName()).isEqualTo(name);
                  assertThat(variable.getValue()).isEqualTo(value);
              });
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/runtime/variableScope.bpmn20.xml" })
      public void testGetVariablesByExecutionIdsForScope() {
          Map<String, Object> processVars = new HashMap<String, Object>();
          processVars.put("processVar", "processVar");
          ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("variableScopeProcess", processVars);
  
          Set<String> executionIds = new HashSet<String>();
          List<Execution> executions = runtimeService
              .createExecutionQuery()
              .processInstanceId(processInstance.getId())
              .list();
          for (Execution execution : executions) {
              if (!processInstance.getId().equals(execution.getId())) {
                  executionIds.add(execution.getId());
                  runtimeService.setVariableLocal(execution.getId(), "executionVar", "executionVar");
              }
          }
  
          List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
          Set<String> taskIds = new HashSet<String>();
          for (Task task : tasks) {
              taskService.setVariableLocal(task.getId(), "taskVar", "taskVar");
              taskIds.add(task.getId());
          }
  
          List<VariableInstance> executionVariableInstances = runtimeService.getVariableInstancesByExecutionIds(
              executionIds
          );
          assertThat(2).isEqualTo(executionVariableInstances.size());
          assertThat("executionVar").isEqualTo(executionVariableInstances.get(0).getName());
          assertThat("executionVar").isEqualTo(executionVariableInstances.get(0).getValue());
          assertThat("executionVar").isEqualTo(executionVariableInstances.get(1).getName());
          assertThat("executionVar").isEqualTo(executionVariableInstances.get(1).getValue());
  
          executionIds = new HashSet<String>();
          executionIds.add(processInstance.getId());
          executionVariableInstances = runtimeService.getVariableInstancesByExecutionIds(executionIds);
          assertThat(1).isEqualTo(executionVariableInstances.size());
          assertThat("processVar").isEqualTo(executionVariableInstances.get(0).getName());
          assertThat("processVar").isEqualTo(executionVariableInstances.get(0).getValue());
      }
  }
  