Apache SCXML 状态机
来源:互联网 发布:time machine 恢复 mac 编辑:程序博客网 时间:2024/06/05 18:40
http://www.javacodegeeks.com/2012/06/apache-commons-scxml-finite-state.html
For full source code visit https://github.com/ozkansari/atmstatemachine
Apache Commons SCXML: Finite State Machine Implementation
atm_status.xml
<pre name="code" class="html"><scxml initial="idle" name="atm.connRestored" version="0.9" xmlns="http://www.w3.org/2005/07/scxml"><!-- node-size-and-position x=0.0 y=0.0 w=1050.0 h=590.0 --> <state id="idle"><!-- node-size-and-position x=40.0 y=220.0 w=100.0 h=100.0 --> <transition event="atm.connected" target="loading"></transition> </state> <state id="loading"><!-- node-size-and-position x=300.0 y=220.0 w=100.0 h=100.0 --> <transition event="atm.loadSuccess" target="inService"></transition> <transition event="atm.connClosed" target="disconnected"></transition> <transition event="atm.loadFail" target="outOfService"></transition> </state> <state id="inService"><!-- node-size-and-position x=570.0 y=30.0 w=100.0 h=100.0 --> <transition event="atm.shutdown" target="outOfService"><!-- edge-path [outOfService] x=580.0 y=190.0 pointx=0.0 pointy=3.0 offsetx=-1.0 offsety=-2.0 --></transition> <transition event="atm.connLost" target="disconnected"><!-- edge-path [disconnected] x=757.0 y=270.0 pointx=0.0 pointy=-12.0 offsetx=13.0 offsety=0.0 --></transition> </state> <state id="outOfService"><!-- node-size-and-position x=570.0 y=260.0 w=100.0 h=100.0 --> <transition event="atm.startup" target="inService"><!-- edge-path [inService] x=660.0 y=190.0 --></transition> <transition event="atm.connLost" target="disconnected"></transition> </state> <state id="disconnected"><!-- node-size-and-position x=570.0 y=450.0 w=100.0 h=100.0 --> <transition event="atm.connRestored" target="inService"><!-- edge-path [inService] x=860.0 y=275.0 --></transition> </state></scxml>
AtmStatusEventEnum.java
package net.javafun.example.atmstatusfsm;public enum AtmStatusEventEnum {CONNECT("atm.connected"), CONNECTION_CLOSED("atm.connClosed"),CONNECTION_LOST("atm.connLost"),CONNECTION_RESTORED("atm.connRestored"),LOAD_SUCCESS("atm.loadSuccess"),LOAD_FAIL("atm.loadFail"),SHUTDOWN("atm.shutdown"),STARTUP("atm.startup"),;private final String eventName;private AtmStatusEventEnum(String eventName) {this.eventName = eventName;}public String getEventName() {return eventName;}public static String getNamesAsCsv(){StringBuilder sb = new StringBuilder();for (AtmStatusEventEnum e : AtmStatusEventEnum.values()) {sb.append(e.name());sb.append(",");}return sb.substring(0,sb.length()-2);}}
AtmStatusFSM.java
package net.javafun.example.atmstatusfsm;import java.util.Collection;import java.util.Set;import org.apache.commons.scxml.env.AbstractStateMachine;import org.apache.commons.scxml.model.State;/** * Atm Status Finite State Machine Example * * @see <a href="http://commons.apache.org/scxml/index.html "> Apache Commons Scxml Library </a> * @author ozkans * */public class AtmStatusFSM extends AbstractStateMachine {/** * State Machine uses this scmxml config file *///private static final String SCXML_CONFIG_ATM_STATUS = "net/javafun/example/atmfsm/atm_status.xml";private static final String SCXML_CONFIG_ATM_STATUS = "atm_status.xml";/* ------------------------------------------------------------------------ *//* CONSTRUCTOR(S) *//* ------------------------------------------------------------------------ */public AtmStatusFSM() { super(AtmStatusFSM.class.getClassLoader().getResource(SCXML_CONFIG_ATM_STATUS));}/* ------------------------------------------------------------------------ *//* HELPER METHOD(S) *//* ------------------------------------------------------------------------ */public void firePreDefinedEvent(AtmStatusEventEnum eventEnum){System.out.println("EVENT: " + eventEnum);this.fireEvent(eventEnum.getEventName());}public void callState(String name){this.invoke(name);}public String getCurrentStateId() {Set<?> states = getEngine().getCurrentStatus().getStates();State state = (State) states.iterator().next();return state.getId();}public State getCurrentState() {Set<?> states = getEngine().getCurrentStatus().getStates();return ( (State) states.iterator().next());}public Collection<?> getCurrentStateEvents() {return getEngine().getCurrentStatus().getEvents();}/* ------------------------------------------------------------------------ */// STATES// // Each method below is the activity corresponding to a state in the// SCXML document (see class constructor for pointer to the document)./* ------------------------------------------------------------------------ */ public void idle() {System.out.println("STATE: idle 被触发"); } public void loading() { System.out.println("STATE: loading 被触发"); } public void inService() { System.out.println("STATE: inService 被触发"); } public void outOfService() { System.out.println("STATE: outOfService 被触发"); } public void disconnected() { System.out.println("STATE: disconnected 被触发"); }}
用Java JFrame UI测试:
package net.javafun.example.atmstatusfsm;import java.awt.BorderLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.List;import java.util.Map;import javax.swing.JButton;import javax.swing.JComboBox;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import org.apache.commons.scxml.model.Transition;import org.apache.commons.scxml.model.TransitionTarget;public class AtmDisplay extends JFrame implements ActionListener {private static final long serialVersionUID = -5083315372455956151L;private AtmStatusFSM atmStatusFSM;private JButton button;private JLabel state;private JComboBox eventComboBox = new JComboBox();public static void main(String[] args) {new AtmDisplay();}public AtmDisplay() {super("ATM Display Demo");atmStatusFSM = new AtmStatusFSM();/* //仅用作测试设置初始化状态,不设置的话使用atm_status.xml里面默认的初始状态@SuppressWarnings("unchecked")Map<String, TransitionTarget> mapTg = atmStatusFSM.getEngine().getStateMachine().getTargets();for(Map.Entry<String, TransitionTarget> entry : mapTg.entrySet()){System.out.println(entry.getKey() + " ==== " + entry.getValue().getId());}TransitionTarget tsTarget = mapTg.get("inService");atmStatusFSM.getEngine().getStateMachine().setInitialTarget(tsTarget); //设置初始状态为inServiceatmStatusFSM.resetMachine();atmStatusFSM.fireEvent(AtmStatusEventEnum.SHUTDOWN.getEventName());*/setupUI();}@SuppressWarnings("deprecation")private void setupUI() {System.out.println("setupUI");JPanel panel = new JPanel();panel.setLayout(new BorderLayout());setContentPane(panel);button = makeButton("FIRE_EVENT", AtmStatusEventEnum.getNamesAsCsv(), "Submit" );panel.add(button, BorderLayout.CENTER);state = new JLabel(atmStatusFSM.getCurrentStateId());panel.add(state, BorderLayout.SOUTH);initEvents();panel.add(eventComboBox, BorderLayout.NORTH);pack();setLocation(200, 200);setResizable(false);setSize(300, 125);show();setDefaultCloseOperation(EXIT_ON_CLOSE);}@SuppressWarnings("unchecked")private void initEvents() {System.out.println("initEvents");eventComboBox.removeAllItems();List<Transition> transitionList = atmStatusFSM.getCurrentState().getTransitionsList();for (Transition transition : transitionList) {eventComboBox.addItem(transition.getEvent() );}}public void actionPerformed(ActionEvent e) {System.out.println("actionPerformed");String command = e.getActionCommand();if(command.equals("FIRE_EVENT")) {checkAndFireEvent();}}private boolean checkAndFireEvent() {System.out.println("checkAndFireEvent");atmStatusFSM.fireEvent(eventComboBox.getSelectedItem().toString());state.setText(atmStatusFSM.getCurrentStateId());initEvents();repaint();return true;}private JButton makeButton(final String actionCommand, final String toolTipText, final String altText) {JButton button = new JButton(altText);button.setActionCommand(actionCommand);button.setToolTipText(toolTipText);button.addActionListener(this);button.setOpaque(false);return button;}}
不用UI测试:
package net.javafun.example.atmstatusfsm;import java.util.List;import java.util.Map;import org.apache.commons.scxml.model.Transition;import org.apache.commons.scxml.model.TransitionTarget;public class TestAtm { public static void main(String[] args) {AtmStatusFSM atmStatusFSM = new AtmStatusFSM();setInitStatus(atmStatusFSM); //仅用作测试设置初始化状态,不设置的话使用atm_status.xml里面默认的初始状态show(atmStatusFSM);show2(atmStatusFSM);//atmStatusFSM.fireEvent(AtmStatusEventEnum.CONNECT.getEventName()); //如果当前状态下没有该Event,那么不会出错,也不会fireEventatmStatusFSM.fireEvent(AtmStatusEventEnum.SHUTDOWN.getEventName());//show2(atmStatusFSM);}private static void setInitStatus(AtmStatusFSM atmStatusFSM) {System.out.println("手动设置初始状态:");Map<String, TransitionTarget> mapTg = atmStatusFSM.getEngine().getStateMachine().getTargets();TransitionTarget tsTarget = mapTg.get("inService");atmStatusFSM.getEngine().getStateMachine().setInitialTarget(tsTarget);atmStatusFSM.resetMachine();System.out.println();}@SuppressWarnings("unchecked")public static void show(AtmStatusFSM atmStatusFSM){System.out.println("列出所有targets:");Map<String,TransitionTarget> mapTg = atmStatusFSM.getEngine().getStateMachine().getTargets();for(Map.Entry<String, TransitionTarget> entry : mapTg.entrySet()){System.out.println(entry.getKey() + " ==== " + entry.getValue().getId());}System.out.println("列出所有States:");Map<String,TransitionTarget> mapSt = atmStatusFSM.getEngine().getStateMachine().getStates();for(Map.Entry<String, TransitionTarget> entry : mapSt.entrySet()){System.out.println(entry.getKey() + " ==== " + entry.getValue().getId());}System.out.println();}public static void show2(AtmStatusFSM atmStatusFSM){System.out.println("列出当前状态及其所有target:");String currentStatus = atmStatusFSM.getCurrentStateId();System.out.println("currentStatus: " + currentStatus);System.out.println("currentStatus's all events: " ); //List<String> list =atmStatusFSM.getCurrentStateEvents();List<Transition> transitionList = atmStatusFSM.getCurrentState().getTransitionsList();for (Transition transition : transitionList) {System.out.println(" " + transition.getEvent());}System.out.println();}}
0 0
- Apache SCXML 状态机
- State Chart XML (SCXML) 状态机规范
- apache common scxml框架学习DEMO
- Apache Commons-SCXML系列之项目介绍
- Apache Commons-SCXML系列之"HelloWorld"
- Apache Commons-SCXML系列之Demo:"秒表"
- Apache Commons-SCXML系列之Demo:"请假流程"
- 《Apache MINA 2.0 用户指南》第十四章:状态机
- Apache mina2 用户指南(十四)状态机
- SCXML有限状态自动机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- Activity Task Final Analysis
- iOS 最新版 CocoaPods 的安装流程
- Data Binding(数据绑定)用户指南
- iOS缓存方案
- mysql中的if与case-when
- Apache SCXML 状态机
- spring quartz学习总结: cluster的配置和示例
- 通过explain对mysql索引优化
- 【实践】ArtTemplate helper函数的使用
- Android编程开发总结
- 如何优雅的退出android应用
- AirPrint: 无交互的后台打印实现(Print without UI,iOS8+)
- 机器学习实战笔记——基于SVD的图像压缩
- 多个字符串逆置