com.googlecode.starflow.engine.support.TriggerProcessEventUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.starflow.engine.support.TriggerProcessEventUtil.java

Source

/*
 * 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.googlecode.starflow.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.googlecode.starflow.core.util.ApplicationContextHolder;
import com.googlecode.starflow.engine.ExecutorService;
import com.googlecode.starflow.engine.ProcessEngine;
import com.googlecode.starflow.engine.ProcessEngineException;
import com.googlecode.starflow.engine.core.Constants;
import com.googlecode.starflow.engine.model.ProcessDefine;
import com.googlecode.starflow.engine.model.ProcessInstance;
import com.googlecode.starflow.engine.model.elements.EventElement;
import com.googlecode.starflow.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);
    }
}