content: package com.alibaba.smart.framework.engine.service.command.impl;
  
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.Map.Entry;
  import java.util.Set;
  
  import com.alibaba.smart.framework.engine.configuration.ProcessEngineConfiguration;
  import com.alibaba.smart.framework.engine.configuration.VariablePersister;
  import com.alibaba.smart.framework.engine.configuration.scanner.AnnotationScanner;
  import com.alibaba.smart.framework.engine.constant.AdHocConstant;
  import com.alibaba.smart.framework.engine.extension.constant.ExtensionConstant;
  import com.alibaba.smart.framework.engine.instance.impl.DefaultVariableInstance;
  import com.alibaba.smart.framework.engine.instance.storage.ActivityInstanceStorage;
  import com.alibaba.smart.framework.engine.instance.storage.ExecutionInstanceStorage;
  import com.alibaba.smart.framework.engine.instance.storage.ProcessInstanceStorage;
  import com.alibaba.smart.framework.engine.instance.storage.TaskAssigneeStorage;
  import com.alibaba.smart.framework.engine.instance.storage.TaskInstanceStorage;
  import com.alibaba.smart.framework.engine.instance.storage.VariableInstanceStorage;
  import com.alibaba.smart.framework.engine.model.instance.ActivityInstance;
  import com.alibaba.smart.framework.engine.model.instance.ExecutionInstance;
  import com.alibaba.smart.framework.engine.model.instance.ProcessInstance;
  import com.alibaba.smart.framework.engine.model.instance.TaskAssigneeInstance;
  import com.alibaba.smart.framework.engine.model.instance.TaskInstance;
  import com.alibaba.smart.framework.engine.model.instance.VariableInstance;
  
  /**
   * Created by 高海军 帝奇 74394 on 2017 February  20:38.
   */
  public abstract  class CommonServiceHelper {
  
  
      public static ProcessInstance insertAndPersist(ProcessInstance processInstance, Map<String, Object> request,
                                                     ProcessEngineConfiguration processEngineConfiguration) {
  
  
          //TUNE 可以在对象创建时初始化,但是这里依赖稍微有点问题
          AnnotationScanner annotationScanner = processEngineConfiguration.getAnnotationScanner();
          ProcessInstanceStorage processInstanceStorage = annotationScanner.getExtensionPoint(
              ExtensionConstant.COMMON,ProcessInstanceStorage.class);
  
          ProcessInstance newProcessInstance =  processInstanceStorage.insert(processInstance, processEngineConfiguration);
  
          persistVariableInstanceIfPossible(request, processEngineConfiguration,
              newProcessInstance, AdHocConstant.DEFAULT_ZERO_VALUE);
  
          persist(newProcessInstance,processEngineConfiguration);
  
          return newProcessInstance;
      }
  
      private static void persistVariableInstanceIfPossible(Map<String, Object> request,
                                                            ProcessEngineConfiguration processEngineConfiguration,
                                                            ProcessInstance newProcessInstance, String executionInstanceId) {
          VariablePersister variablePersister = processEngineConfiguration.getVariablePersister();
          if( variablePersister.isPersisteVariableInstanceEnabled() && null!= request ){
              AnnotationScanner annotationScanner = processEngineConfiguration.getAnnotationScanner();
              VariableInstanceStorage variableInstanceStorage = annotationScanner.getExtensionPoint(ExtensionConstant.COMMON,VariableInstanceStorage.class);
              Iterator<Entry<String, Object>> iterator =request.entrySet().iterator();
              while(iterator.hasNext()){
                  Entry<String, Object> entry = iterator.next();
                  String key = entry.getKey();
  
                  Set<String> blackList = variablePersister.getBlockList();
                  if(null!= blackList && blackList.contains(key)){
                      continue;
                  }
                  
                  
                  Object value = entry.getValue();
                  Class type = value.getClass();
  
                  VariableInstance variableInstance = new DefaultVariableInstance();
                  processEngineConfiguration.getIdGenerator().generate(variableInstance);
                  variableInstance.setProcessInstanceId(newProcessInstance.getInstanceId());
                  variableInstance.setExecutionInstanceId(executionInstanceId);
                  variableInstance.setFieldKey(key);
                  variableInstance.setFieldType(type);
                  variableInstance.setFieldValue(value);
                  variableInstance.setTenantId(newProcessInstance.getTenantId());
  
                  variableInstanceStorage.insert(  variablePersister,variableInstance, processEngineConfiguration);
  
              }
  
          }
      }
  
      public static  ProcessInstance createExecution(String executionInstanceId, ProcessInstance processInstance, Map<String, Object> request,
                                                     ProcessEngineConfiguration processEngineConfiguration) {
  
          AnnotationScanner annotationScanner = processEngineConfiguration.getAnnotationScanner();
          ProcessInstanceStorage processInstanceStorage = annotationScanner.getExtensionPoint(ExtensionConstant.COMMON,ProcessInstanceStorage.class);
  
          ProcessInstance newProcessInstance = processInstanceStorage.update(processInstance,processEngineConfiguration );
  
          persistVariableInstanceIfPossible(request, processEngineConfiguration,
              newProcessInstance,executionInstanceId);
  
          persist(processInstance   ,  processEngineConfiguration );
  
          return newProcessInstance;
      }
  
  
  
      private static void persist(ProcessInstance processInstance, ProcessEngineConfiguration processEngineConfiguration ) {
  
          AnnotationScanner annotationScanner = processEngineConfiguration.getAnnotationScanner();
          ActivityInstanceStorage activityInstanceStorage= annotationScanner.getExtensionPoint(ExtensionConstant.COMMON,ActivityInstanceStorage.class);
          ExecutionInstanceStorage executionInstanceStorage=annotationScanner.getExtensionPoint(ExtensionConstant.COMMON,ExecutionInstanceStorage.class);
          TaskInstanceStorage taskInstanceStorage=annotationScanner.getExtensionPoint(ExtensionConstant.COMMON,TaskInstanceStorage.class);
          TaskAssigneeStorage taskAssigneeStorage = annotationScanner.getExtensionPoint(ExtensionConstant.COMMON,TaskAssigneeStorage.class);
  
  
          List<ActivityInstance> activityInstances = processInstance.getActivityInstances();
          for (ActivityInstance activityInstance : activityInstances) {
  
              activityInstance.setProcessInstanceId(processInstance.getInstanceId());
              activityInstanceStorage.insert(activityInstance,processEngineConfiguration );
  
              List<ExecutionInstance> executionInstanceList = activityInstance.getExecutionInstanceList();
  
              if(null != executionInstanceList){
                  for (ExecutionInstance executionInstance : executionInstanceList) {
                      persistInstance( executionInstanceStorage, taskInstanceStorage,taskAssigneeStorage,
                          activityInstance,
                          executionInstance,  processEngineConfiguration);
                  }
              }
  
          }
  
      }
  
      //TUNE too many args
      private static void persistInstance(ExecutionInstanceStorage executionInstanceStorage,
                                          TaskInstanceStorage taskInstanceStorage, TaskAssigneeStorage taskAssigneeStorage, ActivityInstance activityInstance,
                                          ExecutionInstance executionInstance, ProcessEngineConfiguration processEngineConfiguration) {
          if (null != executionInstance) {
              executionInstance.setProcessInstanceId(activityInstance.getProcessInstanceId());
              executionInstance.setActivityInstanceId(activityInstance.getInstanceId());
              executionInstanceStorage.insert(executionInstance,processEngineConfiguration );
  
              TaskInstance taskInstance = executionInstance.getTaskInstance();
              if(null!= taskInstance) {
                  taskInstance.setActivityInstanceId(executionInstance.getActivityInstanceId());
                  taskInstance.setProcessInstanceId(executionInstance.getProcessInstanceId());
                  taskInstance.setExecutionInstanceId(executionInstance.getInstanceId());
  
                  //reAssign
                  taskInstance = taskInstanceStorage.insert(taskInstance,processEngineConfiguration );
  
                  List<TaskAssigneeInstance>  taskAssigneeInstances =  taskInstance.getTaskAssigneeInstanceList();
  
                  if(null != taskAssigneeInstances){
                      for (TaskAssigneeInstance taskAssigneeInstance : taskAssigneeInstances) {
                          taskAssigneeInstance.setTaskInstanceId(taskInstance.getInstanceId());
                          taskAssigneeInstance.setProcessInstanceId(taskInstance.getProcessInstanceId());
                          taskAssigneeStorage.insert(taskAssigneeInstance,processEngineConfiguration );
                      }
                  }
  
                  executionInstance.setTaskInstance(taskInstance);
              }
  
  
          }
      }
      
      
  	public static void createExecution(ExecutionInstance executionInstance, ProcessEngineConfiguration processEngineConfiguration) {
  		AnnotationScanner annotationScanner = processEngineConfiguration.getAnnotationScanner();
  		ExecutionInstanceStorage executionInstanceStorage=annotationScanner.getExtensionPoint(ExtensionConstant.COMMON,ExecutionInstanceStorage.class);
  		if (null != executionInstance) {
              executionInstanceStorage.insert(executionInstance,processEngineConfiguration );
          }
  	}
  
  }
  