Created
June 6, 2012 12:53
-
-
Save ozkansari/2881653 to your computer and use it in GitHub Desktop.
Atm Status Finite State Machine Example using Apache Commons SCXML Library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<scxml initial="idle" name="atm.connRestored" version="0.9" | |
xmlns="http://www.w3.org/2005/07/scxml"> | |
<state id="idle"> | |
<transition event="atm.connected" target="loading"></transition> | |
</state> | |
<state id="loading"> | |
<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"> | |
<transition event="atm.shutdown" target="outOfService"></transition> | |
<transition event="atm.connLost" target="disconnected"></transition> | |
</state> | |
<state id="outOfService"> | |
<transition event="atm.startup" target="inService"></transition> | |
<transition event="atm.connLost" target="disconnected"></transition> | |
</state> | |
<state id="disconnected"> | |
<transition event="atm.connRestored" target="inService"></transition> | |
</state> | |
</scxml> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.javafun.example.atmstatusfsm; | |
import java.awt.BorderLayout; | |
import java.awt.event.ActionEvent; | |
import java.awt.event.ActionListener; | |
import java.util.List; | |
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; | |
/** | |
* Atm Status Change GUI | |
* | |
* @author ozkansari.com | |
* | |
*/ | |
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(); | |
setupUI(); | |
} | |
@SuppressWarnings("deprecation") | |
private void 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() { | |
eventComboBox.removeAllItems(); | |
List transitionList = atmStatusFSM.getCurrentState().getTransitionsList(); | |
for (Transition transition : transitionList) { | |
eventComboBox.addItem(transition.getEvent() ); | |
} | |
} | |
public void actionPerformed(ActionEvent e) { | |
String command = e.getActionCommand(); | |
if(command.equals("FIRE_EVENT")) { | |
checkAndFireEvent(); | |
} | |
} | |
private boolean 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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.javafun.example.atmstatusfsm; | |
/** | |
* Atm Status Change Events | |
* | |
* @author ozkansari.com | |
* | |
*/ | |
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
* | |
* @see Apache Commons Scxml Library | |
* @author ozkansari.com | |
* | |
*/ | |
public class AtmStatusFSM extends AbstractStateMachine { | |
/** | |
* State Machine uses this scmxml config file | |
*/ | |
private static final String SCXML_CONFIG_ATM_STATUS = "net/javafun/example/atmstatusfsm/atm_status.xml"; | |
/* CONSTRUCTOR(S) */ | |
public AtmStatusFSM() { | |
super(AtmStatusFSM.class.getClassLoader().getResource(SCXML_CONFIG_ATM_STATUS)); | |
} | |
/* HELPER METHOD(S) */ | |
/* | |
* Fire the event | |
*/ | |
public void firePreDefinedEvent(AtmStatusEventEnum eventEnum){ | |
System.out.println("EVENT: " + eventEnum); | |
this.fireEvent(eventEnum.getEventName()); | |
} | |
public void callState(String name){ | |
this.invoke(name); | |
} | |
/* | |
* Get current state ID as string | |
*/ | |
public String getCurrentStateId() { | |
Set states = getEngine().getCurrentStatus().getStates(); | |
State state = (State) states.iterator().next(); | |
return state.getId(); | |
} | |
/* | |
* Get current state as apache's State object | |
*/ | |
public State getCurrentState() { | |
Set states = getEngine().getCurrentStatus().getStates(); | |
return ( (State) states.iterator().next()); | |
} | |
/* | |
* Get events belongs to current status of the FSM | |
*/ | |
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"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment