`
deepthink
  • 浏览: 56821 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

流程图状态机DEMO(附件wf-statemachine-demo.rar下载)

阅读更多

这是我写的一个DEOM,目的在于对 

 

jquery 简易的流程图编辑控件 新版(20100907)

的一个流程支持而写的状态机DEMO

 

表达式使用IK EXPRESSION,以后会支持EL,也可能会支持JS,或者其他的脚本语言

 

没有测试,默认实现还有错误,以后会更新稳定版本的

 

下面是其中的部分代码:

 

 

package keng.core.workflow.state.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.TimeoutException;

import keng.core.util.StringUtil;
import keng.core.workflow.state.ISMActionProcessor;
import keng.core.workflow.state.ISMContext;
import keng.core.workflow.state.ISMListener;
import keng.core.workflow.state.ISMNode;
import keng.core.workflow.state.ISMTransition;
import keng.core.workflow.state.ISMTransitionMatcher;
import keng.core.workflow.state.IStateMachine;
import keng.core.workflow.state.StateMachineException;

/**
 * 默认的状态机实现
 * 
 * @author 5Di
 * 
 */
public class DefaultStateMachine implements IStateMachine {

	/**
	 * 自动节点的默认动作
	 */
	public static final String ACTION_DEFAULT = "send";

	/**
	 * 进入循环后的最大循环次数
	 */
	public static final int MAX_DEEPTH = 6;

	// --------------------

	Stack<ISMNode> register = new Stack<ISMNode>();

	ISMTransitionMatcher matcher;

	ISMContext context;

	ISMActionProcessor processor;

	List<ISMListener> listeners;

	/**
	 * 根节点
	 */
	ISMNode nodeMap;

	boolean strict = false;

	public DefaultStateMachine(ISMNode nodeMap, ISMContext context) {
		this.context = context;
		this.nodeMap = nodeMap;
	}

	public DefaultStateMachine(ISMNode nodeMap, ISMContext context,
			ISMTransitionMatcher matcher) {
		this.nodeMap = nodeMap;
		this.context = context;
		this.matcher = matcher;
	}

	public DefaultStateMachine(ISMNode nodeMap, ISMContext context,
			ISMTransitionMatcher matcher, boolean strict) {
		this.context = context;
		this.nodeMap = nodeMap;
		this.matcher = matcher;
		this.strict = strict;
	}

	@Override
	public boolean transit(ISMNode node, String action, String state)
			throws StateMachineException, TimeoutException {
		if (action == null || action.isEmpty())
			throw new IllegalArgumentException("action can not be empty!");

		if (StringUtil.isEmpty(state))
			throw new IllegalArgumentException("state can not be empty!");

		if (node == null)
			throw new IllegalArgumentException("node can not be null!");

		List<ISMTransition> transitions = node.getTransitions();

		if (transitions == null || transitions.isEmpty())
			throw new StateMachineException("transitions can not be empty !");

		// 检查节点图,限制自动节点的转化深度
		if (node.isAuto())
			if (!checkNodeMap(node))
				throw new TimeoutException("die cycle");

		boolean b = false;
		for (ISMTransition transition : transitions) {
			boolean bool = transit(transition, action, state, node);

			if (bool) {
				b = true;
				if (register.indexOf(node) == -1)
					register.push(node);

				this.fireNodeTransit(node, state, transition.getToState());

				if (node.isAuto())
					this.fireAutoNodeTransit(node, state,
							transition.getToState());
			}
		}

		transitNextAutoNodes(node);

		return b;
	}

	/**
	 * 转换 parent的直接下级自动节点<br />
	 * 当遇到非自动节点时,自动结束
	 * 
	 * @param parent
	 * @throws StateMachineException
	 * @throws TimeoutException
	 */
	void transitNextAutoNodes(ISMNode parent) throws StateMachineException,
			TimeoutException {
		List<ISMNode> children = parent.getNextAutoNodes();
		if (children != null && !children.isEmpty()) {
			for (ISMNode child : children) {
				String action = child.getAction();

				if (action == null || action.isEmpty())
					action = ACTION_DEFAULT;

				transit(child, action, child.getState());
			}
		}
	}

	/**
	 * 
	 * @param transition
	 * @param action
	 * @param state
	 * @param node
	 * @return
	 * @throws StateMachineException
	 * @throws TimeoutException
	 * 
	 * @return 该transition 是否被执行
	 */
	boolean transit(ISMTransition transition, String action, String state,
			ISMNode node) throws StateMachineException, TimeoutException {
		boolean b = matcher.match(context, transition, action, state, strict);

		this.fireTransitionMatch(action, state, transition, b);

		if (!b)
			return false;
		else {
			this.fireTransitionMatched(action, state, transition);
		}

		// process action
		processor.process(transition);

		node.setState(transition.getToState());
		return true;
	}

	/**
	 * 检查节点图,防止进入死循环<br />
	 * 
	 * @param node
	 * @return 是否成功
	 */
	public boolean checkNodeMap(ISMNode node) {
		int i = 0;

		Iterator<ISMNode> it = register.iterator();
		while (it.hasNext()) {
			i = node.equals(it.next()) ? i + 1 : i;
		}

		return i <= MAX_DEEPTH;
	}

	@Override
	public boolean removeListener(ISMListener listener) {
		if (listeners == null || listeners.isEmpty())
			return false;

		if (!listeners.contains(listener))
			return false;

		listeners.remove(listener);

		return true;
	}

	@Override
	public void addListener(ISMListener listener) {
		if (listeners == null)
			listeners = new ArrayList<ISMListener>();

		listeners.add(listener);
	}

	@Override
	public boolean existsListener(ISMListener listener) {
		if (listeners == null || listeners.isEmpty())
			return false;

		return listeners.contains(listener);
	}

	/**
	 * 响应事件
	 * 
	 * @param node
	 * @param fromState
	 * @param toState
	 */
	void fireNodeTransit(ISMNode node, String fromState, String toState) {
		if (listeners == null || listeners.isEmpty())
			return;

		for (ISMListener listener : listeners)
			listener.onNodeTransit(node, fromState, toState);
	}

	/**
	 * 
	 * @param node
	 * @param fromState
	 * @param toState
	 */
	void fireAutoNodeTransit(ISMNode node, String fromState, String toState) {
		if (listeners == null || listeners.isEmpty())
			return;

		for (ISMListener listener : listeners)
			listener.onAutoNodeTransit(node, fromState, toState);
	}

	/**
	 * 响应事件
	 * 
	 * @param action
	 * @param state
	 * @param transition
	 * @param matched
	 */
	void fireTransitionMatch(String action, String state,
			ISMTransition transition, boolean matched) {
		if (listeners == null || listeners.isEmpty())
			return;

		for (ISMListener listener : listeners)
			listener.onTransitionMatch(action, state, transition, matched);
	}

	/**
	 * 响应事件
	 * 
	 * @param action
	 * @param state
	 * @param transition
	 */
	void fireTransitionMatched(String action, String state,
			ISMTransition transition) {
		if (listeners == null || listeners.isEmpty())
			return;

		for (ISMListener listener : listeners)
			listener.onTransitionMatched(action, state, transition);
	}
}
 

 

 

package keng.core.workflow.state;

import java.util.concurrent.TimeoutException;

/**
 * 状态机模型
 * 
 * @author 5Di
 * 
 */
public interface IStateMachine {

	/**
	 * 执行<br />
	 * 挨个try transition ,遇到第一个成功,理解返回<br />
	 * 执行逻辑:先匹配action 和 fromState ,然后calculate condition <br />
	 * 匹配策略,先匹配action,再匹配fromState,最后是condition<br />
	 * 
	 * @param action
	 *            当前执行的行为
	 * 
	 * @param state
	 *            当前的状态
	 * @param node
	 *            当前操作的节点
	 * 
	 * @return 是否被执行(如果自动执行的子节点返回了false,也会返回false),false并不说明没有成功,因为如果步骤进入了死循环(
	 *         系统自动执行的的步骤之间会进入死循环) ,在这种情况下不会抛出异常,而是直接返回false
	 */
	public boolean transit(String action, String state, ISMNode node)
			throws StateMachineException, TimeoutException;

}

 

 

 

package keng.core.workflow.state;

/**
 * 状态机条件
 * 
 * @author 5Di
 * 
 */
public interface ISMTransition {

	/**
	 * 条件
	 * 
	 * @return
	 */
	public ISMCondition getCondition();

	/**
	 * 动作
	 * 
	 * @return
	 */
	public String getAction();

	/**
	 * 处理器
	 * 
	 * @return
	 */
	public ISMActionProcessor getActionProcessor();

	/**
	 * 原始状态
	 * 
	 * @return
	 */
	public String getFromState();

	/**
	 * 目标状态
	 * 
	 * @return
	 */
	public String getToState();
}

 

package keng.core.workflow.state;

import java.util.Map;

import keng.core.workflow.model.WfStep;
import keng.core.workflow.model.WorkFlow;

/**
 * 上下文环境
 * @author 5Di
 *
 */
public interface ISMContext extends Map<String,Object>{

	public WorkFlow getWorkFlow();
	
	public String getAction();
	
	public WfStep getStep();
	
}

 package keng.core.workflow.state;

 

/**
 * Action处理器<br />
 * 当Transit Transition 的时候,会执行相应的Action处理器,一般实现类会执行特定的业务代码
 * 
 * @author 5Di
 * 
 */
public interface ISMActionProcessor {

	/**
	 * 处理
	 * 
	 * @return
	 */
	public Object process() throws StateMachineException;

	public void beforeProcess() throws StateMachineException;

	public void afterProcess() throws StateMachineException;
}

 

其他的还有:ISMNode.java,ISMCondition.java.. 就不贴出来了

 

下面是DefaultStateMachine.java 是IStateMachine.java的默认实现

 

 

package keng.core.workflow.state.impl;

import java.util.List;
import java.util.Stack;
import java.util.concurrent.TimeoutException;

import keng.core.util.StringUtil;
import keng.core.workflow.state.ISMActionProcessor;
import keng.core.workflow.state.ISMCondition;
import keng.core.workflow.state.ISMContext;
import keng.core.workflow.state.ISMNode;
import keng.core.workflow.state.ISMTransition;
import keng.core.workflow.state.ISMTransitionMatcher;
import keng.core.workflow.state.IStateMachine;
import keng.core.workflow.state.StateMachineException;

/**
 * 默认的状态机实现
 * 
 * @author 5Di
 * 
 */
public class DefaultStateMachine implements IStateMachine {

	Stack<ISMNode> register = new Stack<ISMNode>();

	ISMTransitionMatcher matcher;

	ISMContext context;

	/**
	 * 根节点
	 */
	ISMNode root;

	boolean strict = false;

	public DefaultStateMachine(ISMNode root, ISMContext context) {
		this.context = context;
		this.root = root;
	}

	public DefaultStateMachine(ISMNode root, ISMContext context,
			ISMTransitionMatcher matcher) {
		this.root = root;
		this.context = context;
		this.matcher = matcher;
	}

	public DefaultStateMachine(ISMNode root, ISMContext context,
			ISMTransitionMatcher matcher, boolean strict) {
		this.context = context;
		this.root = root;
		this.matcher = matcher;
		this.strict = strict;
	}

	@Override
	public boolean transit(String action, String state, ISMNode node)
			throws StateMachineException, TimeoutException {
		if (StringUtil.isEmpty(action))
			throw new IllegalArgumentException("action can not be empty!");

		if (StringUtil.isEmpty(state))
			throw new IllegalArgumentException("state can not be empty!");

		if (node == null)
			throw new IllegalArgumentException("node can not be null!");

		List<ISMTransition> transitions = node.getTransitions();

		if (transitions == null || transitions.isEmpty())
			throw new StateMachineException("transitions can not be empty !");

		// check che node
		if (checkNodeMap(node))
			return false;

		// Match the transition
		ISMTransition transition = matchTransition(action, state, transitions);

		boolean b = false;

		ISMCondition condition = transition.getCondition();
		if (condition == null)
			if (!strict)
				b = true;
			else
				throw new StateMachineException(
						"transition's condition can not be null!");

		b = condition.calculate(context, strict);

		if (!b)
			throw new TimeoutException("no transition was matched!");

		// process action
		ISMActionProcessor processor = transition.getActionProcessor();
		processor.process();

		register.push(node);

		// auto process next auto steps
		List<ISMNode> children = node.getChildren();
		if (children != null && !children.isEmpty()) {
			for (ISMNode child : children) {
				transit(action, state, child);
			}
		}

		node.setState(transition.getToState());

		return true;
	}

	/**
	 * 匹配transition <br />
	 * 使用<code>keng.core.workflow.state.ISMTransitionMatcher.match</code>匹配
	 * 
	 * @param action
	 * @param state
	 * @param transitions
	 * @return
	 */
	ISMTransition matchTransition(String action, String state,
			List<ISMTransition> transitions) {
		if (matcher == null)
			matcher = new DefaultSMTransitionMatcher();

		transitions = matcher.sort(transitions);

		int i, len = transitions.size();
		for (i = 0; i < len; i++) {
			ISMTransition transition = transitions.get(i);
			if (matcher.match(action, state, transition))
				return transition;
		}

		return null;
	}

	/**
	 * 检查节点图,是否进入了死循环<br />
	 * 目前还不完备,只是检查了已经执行过的node
	 * 
	 * @param node
	 * @return 如果已经执行,返回true
	 */
	public boolean checkNodeMap(ISMNode node) {
		return register.indexOf(node) != -1;
	}
}

 

 

目前还处于DEMO 状态,如果大家有想要说的,尽管拍砖,共同进步

最后,给大家提供两个工作流方面的资料

《工作流模型分析》和《工作流管理联盟规范》

 

0
0
分享到:
评论
1 楼 ytqwz 2014-11-16  
楼主,现在完成的怎么样了

相关推荐

    管理订单状态,该上状态机吗?轻量级状态机COLA StateMachine保姆级入门教程.doc

    本篇文章将围绕轻量级状态机COLA StateMachine,讲解其概念、优点以及在订单状态管理中的实际应用。 首先,我们需要理解状态机(State Machine)在软件工程中的概念。状态机是一种计算模型,它可以用来设计系统中的...

    PyPI 官网下载 | cdk-demo-construct-0.0.17.tar.gz

    《PyPI官网下载:深入解析cdk-demo-construct-0.0.17.tar.gz》 PyPI(Python Package Index)是Python社区广泛使用的软件包仓库,它为开发者提供了便捷的方式来发布、查找和安装Python软件包。在本篇文章中,我们将...

    通用有限状态机(FSM: Finite-state machine)自动代码生成器

    通用有限状态机(FSM: Finite-state machine)自动代码生成器. 可以根据配置文件,自动生成状态机代码(C++)。配置文件中只需要定义状态,跃迁条件。然后完善每个状态的动作即可。省去开发过程中手写状态机的麻烦。...

    liquid-state-machine:从 code.google.compliquid-state-machine 自动导出

    液态状态机 (LSM) 是一种使用时间神经元进行计算的方法,与标准人工神经网络不同,它可用于直接对固有时间数据进行分类。 它也被提出作为某些大脑功能的自然模型。 通过这段代码,我们表明通常由 Maass 等人定义的...

    Query-state-machine-core-code.zip_Labview状态机_Query Machine_labvi

    在这个"Query-state-machine-core-code.zip_Labview状态机_Query Machine_labvi"压缩包中,包含的核心是LabVIEW的状态机实现,这是一种非常重要的编程模式,用于管理程序的不同阶段和行为。 状态机在LabVIEW中的...

    RTL8365MB-DEMO-LQFP128-P4L-SCH-v.1.0.zip_DEMO_land3mf_交换机原理图_交换机

    原理图详细描绘了各个接口和信号线的连接方式,包括电源管理、时钟配置、PHY接口、控制与状态寄存器访问,以及与外部存储器的交互等关键部分。通过分析这份图纸,开发者可以理解如何正确布局和布线,以确保数据传输...

    stateflow逻辑系统建模的部分程序-stateflow.rar

    stateflow逻辑系统建模的部分程序-stateflow.rar 文件中包含流程图、在动作中执行事件、状态执行顺序三个文件夹和一个word文档,简介如下: 流程图包含: stateflow_xuanzejiegou.mdl--------用stateflow搭建...

    Android-StateMachine-用于有限状态机的KotlinDSL

    在Android应用开发中,有限状态机(Finite State Machine, FSM)是一种常见的设计模式,它将一个系统的各种行为抽象为不同的状态,并定义了状态之间的转换规则。`Android-StateMachine`库提供了一个基于Kotlin的领域...

    前端开源库-stampit-state-machine

    `stampit-state-machine` 是一个基于 Stampit 库实现的状态机接口,它为前端开发者提供了一种简单而有效的方式来管理和控制组件的状态转换。 Stampit 是一个轻量级的 JavaScript 工具,它允许创建可组合的对象,通过...

    mark-react-spa-demo--intro-to-state-源码.rar

    标题中的"mark-react-spa-demo--intro-to-state-源码.rar"表明这是一个关于React单页应用(SPA)的示例项目,重点在于介绍如何管理组件的状态。源码压缩包通常包含了一个运行在React框架下的单页应用的完整结构,...

    Fluent-State-Machine, 在 C# 中,用于创建状态机的Fluent API.zip

    Fluent-State-Machine, 在 C# 中,用于创建状态机的Fluent API Fluent-State-Machine C# 中创建层次有限状态机的API 。使用单个状态机创建一个状态机。条件使用多个状态变量的嵌套状态推送和pop嵌套状态事件自定义...

    stateMachine状态机框架

    - stateMachine.c:这是框架的源文件,其中应该实现了stateMachine.h头文件中声明的功能,包括状态机的初始化、状态转换、事件处理等核心逻辑。 - main.c:这是一个示例程序的主文件,它使用状态机框架来实现具体的...

    uniform-pay-demo.rar_.afc demo_DE106_京东支付_京东支付DEMO_京东支付接口

    本文将基于“uniform-pay-demo.rar_.afc demo_DE106_京东支付_京东支付DEMO_京东支付接口”这一资源,详细解析京东支付的开放接口Demo,帮助开发爱好者更好地理解和应用。 首先,"uniform-pay-demo"是京东支付接口...

    安卓机顶盒相关-机顶盒应用的demo.rar

    【标题解析】:“安卓机顶盒相关-机顶盒应用的demo.rar”表明这是一个与安卓机顶盒相关的项目,其中包含的应用程序demo是为安卓机顶盒设计的。"demo"通常指的是演示或示例代码,用于展示特定功能或技术。 【描述...

    Atom-atom-state-machine-cat-preview,用于编写(和预览)漂亮的状态机图表的atom包.zip

    Atom-atom-state-machine-cat-preview.zip,用于编写(和预览)漂亮的状态机图表的atom包atom状态机cat预览包,atom是一个用web技术构建的开源文本编辑器。

    apache-tomcat-7.0.70.tar.gz

    然后,`.gz`表示这个归档文件经过了gzip程序的压缩,以减小文件大小,提高下载速度。 **解压步骤**: 在Linux环境下,可以使用以下命令来解压并提取Tomcat文件: ```bash $ tar -zxvf apache-tomcat-7.0.70.tar.gz...

    微信小程序Demo--大好商城,wechat-weapp-附完整源代码.rar

    微信小程序Demo–大好商城,是一个集商品浏览、购买、支付等功能于一体的综合性线上购物平台。通过这个Demo,用户可以体验到类似京东、淘宝等主流电商平台的购物功能,同时开发者也可以在此基础上进行二次开发和定制...

    curl-7.33.0-win64-ssl-sspi.zip

    例如,最基本的使用方式是`curl [URL]`,这将下载指定URL的资源。通过添加不同的选项,可以实现更复杂的操作,如: - `-L`:跟随重定向,自动处理服务器返回的HTTP状态码301或302。 - `-o`或`--output`: 指定保存...

    spring-statemachine-2.02.release源码

    1. **状态机模型**:Spring StateMachine 基于 UML 状态图模型,包括状态(State)、事件(Event)、转换(Transition)和行为(Action)。每个状态可以包含子状态,事件触发状态间的转换,而行为则在转换过程中执行...

Global site tag (gtag.js) - Google Analytics