Package com.starflow.wf.engine.support

Source Code of com.starflow.wf.engine.support.TriggerProcessEventUtil$IAction

/*
* Copyright 2010-2011 the original author or authors.
*
* 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 com.starflow.wf.engine.support;

import java.util.List;
import java.util.concurrent.Callable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.starflow.wf.core.util.ApplicationContextHolder;
import com.starflow.wf.engine.ExecutorService;
import com.starflow.wf.engine.ProcessEngine;
import com.starflow.wf.engine.ProcessEngineException;
import com.starflow.wf.engine.core.Constants;
import com.starflow.wf.engine.model.ProcessDefine;
import com.starflow.wf.engine.model.ProcessInstance;
import com.starflow.wf.engine.model.elements.EventElement;
import com.starflow.wf.service.spi.IProcessTriggerEvent;

/**
* 流程和环节调用触发事件帮助类。
*
* @author libinsong1204@gmail.com
* @version 1.0
*/
public class TriggerProcessEventUtil {
  private static Logger logger = LoggerFactory.getLogger(TriggerProcessEventUtil.class);
 
  /**
   * 流程启动前
   *
   * @param processEngine
   * @param processInstId
   * @param triggerEvents
   */
  public static void beforeStart(ProcessEngine processEngine, ProcessDefine processDefine,
      ProcessInstance processInstance, List<EventElement> triggerEvents) {
    for(final EventElement eventXml : triggerEvents) {
      if(TriggerEventType.BEFORE_START_PROC.equals(eventXml.getEventType())) {
        action(processEngine, processDefine, processInstance, eventXml, new IAction() {
         
          @Override
          public void execute(ProcessDefine processDefine, ProcessInstance processInstance) {
            IProcessTriggerEvent processTriggerEvent =
              (IProcessTriggerEvent)ApplicationContextHolder.getBean(eventXml.getAction());
            processTriggerEvent.beforeStart(processDefine.getProcessDefId());
          }
        });
      }
    }
  }
 
  /**
   * 流程启动后
   *
   * @param processEngine
   * @param processInstId
   * @param triggerEvents
   */
  public static void afterStart(ProcessEngine processEngine, ProcessDefine processDefine,
      ProcessInstance processInstance, List<EventElement> triggerEvents) {
    for(final EventElement eventXml : triggerEvents) {
      if(TriggerEventType.AFTER_START_PROC.equals(eventXml.getEventType())) {
        action(processEngine, processDefine, processInstance, eventXml, new IAction() {
         
          @Override
          public void execute(ProcessDefine processDefine, ProcessInstance processInstance) {
            IProcessTriggerEvent processTriggerEvent =
              (IProcessTriggerEvent)ApplicationContextHolder.getBean(eventXml.getAction());
            processTriggerEvent.afterStart(processInstance.getProcessInstId());
          }
        });
      }
    }
  }
 
  /**
   * 流程完成前
   *
   * @param processEngine
   * @param processInstId
   * @param triggerEvents
   */
  public static void beforeComplete(ProcessEngine processEngine, ProcessDefine processDefine,
      ProcessInstance processInstance, List<EventElement> triggerEvents) {
    for(final EventElement eventXml : triggerEvents) {
      if(TriggerEventType.BEFORE_COMPLETE_PROC.equals(eventXml.getEventType())) {
        action(processEngine, processDefine, processInstance, eventXml, new IAction() {
         
          @Override
          public void execute(ProcessDefine processDefine, ProcessInstance processInstance) {
            IProcessTriggerEvent processTriggerEvent =
              (IProcessTriggerEvent)ApplicationContextHolder.getBean(eventXml.getAction());
            processTriggerEvent.beforeComplete(processInstance.getProcessInstId());
          }
        });
      }
    }
  }
 
  /**
   * 流程完成后
   *
   * @param processEngine
   * @param processInstId
   * @param triggerEvents
   */
  public static void afterComplete(ProcessEngine processEngine, ProcessDefine processDefine,
      ProcessInstance processInstance, List<EventElement> triggerEvents) {
    for(final EventElement eventXml : triggerEvents) {
      if(TriggerEventType.AFTER_COMPLETE_PROC.equals(eventXml.getEventType())) {
        action(processEngine, processDefine, processInstance, eventXml, new IAction() {
         
          @Override
          public void execute(ProcessDefine processDefine, ProcessInstance processInstance) {
            IProcessTriggerEvent processTriggerEvent =
              (IProcessTriggerEvent)ApplicationContextHolder.getBean(eventXml.getAction());
            processTriggerEvent.afterComplete(processInstance.getProcessInstId());
          }
        });
      }
    }
  }

  /**
   * 执行触发事件
   *
   * 异步执行触发事件,使用suspend事务策略,忽略异常。
   * 同步调用
   *        join事务策略。回滚和忽略异常两种处理方式
   *        suspend事务策略。回滚和忽略异常两种处理方式
   *
   * @param processEngine
   * @param processInstId
   * @param eventXml
   * @param action
   */
  private static void action(ProcessEngine processEngine, final ProcessDefine processDefine,
      final ProcessInstance processInstance, EventElement eventXml, final IAction action) {
    String invokePattern = eventXml.getInvokePattern();
    final String transactionType = eventXml.getTransactionType();
   
    ExecutorService executor = processEngine.getExecutorService();
    if(Constants.ACT_AUTO_CALL_SYN.equalsIgnoreCase(invokePattern)) {
      //同步调用可以返回运行结果,前提是要设置返回运行结果。
      try {
        executor.execute(new Callable<Object>() {
          public Object call() throws Exception {
            if(Constants.ACT_TRANSACTION_JOIN.equalsIgnoreCase(transactionType)) {
              action.execute(processDefine, processInstance);
            } else {
              executeLogicInNewTransaction(processDefine, processInstance, action);
            }
            return null;
          }
        }, invokePattern);
      } catch (Exception e) {
        handleException(e, eventXml);
      }
    } else {
      //异步执行使用suspend事务。忽略异常
      try {
        executor.execute(new Callable<Object>() {
          public Object call() throws Exception {
            executeLogicInNewTransaction(processDefine, processInstance, action);
            return null;
          }
        }, invokePattern);
      } catch (Exception e) {
        logger.error("自动环节Action执行失败", e);
      }
    }
  }
 
  /**
   *
   * @param e
   * @param eventXml
   */
  private static void handleException(Exception e, EventElement eventXml) {
    String exceptionStrategy = eventXml.getExceptionStrategy();
   
    if(Constants.ACT_EXCEPTIONSTRATEGY_ROLLBACK.equals(exceptionStrategy))
      throw new ProcessEngineException("触发事件执行失败", e);
    else {
      logger.error("触发事件执行失败", e);
    }
  }
 
  /**
   * 挂起当前事务,在一个新事物中执行业务逻辑
   *
   * @param processInstId
   * @param action
   * @return
   */
  private static void executeLogicInNewTransaction(ProcessDefine processDefine,
      ProcessInstance processInstance, IAction action) {
    PlatformTransactionManager txManager = ApplicationContextHolder.getBean(PlatformTransactionManager.class);
    DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
    definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    TransactionStatus status = txManager.getTransaction(definition);
    try {
      action.execute(processDefine, processInstance);
      txManager.commit(status);
    } catch (Exception e) {
      txManager.rollback(status);
      throw new ProcessEngineException("触发事件执行失败", e);
    }
  }
 
  private static interface IAction {
    public void execute(ProcessDefine processDefine, ProcessInstance processInstance);
  }
}
TOP

Related Classes of com.starflow.wf.engine.support.TriggerProcessEventUtil$IAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.