Skip to content

Instantly share code, notes, and snippets.

@ar
Created May 21, 2012 18:44
Show Gist options
  • Save ar/2763871 to your computer and use it in GitHub Desktop.
Save ar/2763871 to your computer and use it in GitHub Desktop.
FSM Implementation
// Model:
/*
* Copyright (c) 2004 jPOS.org
*
* See terms of license at http://jpos.org/license.html
*
*/
package org.jpos.fsm;
import java.util.*;
import org.jdom.Element;
/**
* @author Alejandro Revilla
*/
public class Model {
HashMap states;
State initialState = null;
public Model (Element model) {
super ();
states = new HashMap ();
initModel (model);
}
private void initModel (Element e) {
Iterator iter = e.getChildren ("state").iterator ();
while (iter.hasNext ()) {
initState ((Element) iter.next ());
}
}
public State getInitialState () {
return initialState;
}
private void initState (Element e) {
State s = new State (e.getAttributeValue ("name"));
states.put (s.getName (), s);
if (initialState == null)
initialState = s;
s.setSelector (e.getChildTextTrim ("selector"));
Iterator iter = e.getChildren ("transition").iterator ();
while (iter.hasNext ()) {
initTransition (s, (Element) iter.next ());
}
}
private void initTransition (State s, Element e) {
s.addTransition (
e.getAttributeValue ("name"),
e.getAttributeValue ("next", "nil"),
e.getAttributeValue ("action")
);
}
public State getState (String name) {
return (State) states.get (name);
}
}
// State
/*
* Copyright (c) 2004 jPOS.org
*
* See terms of license at http://jpos.org/license.html
*
*/
package org.jpos.fsm;
import java.util.Map;
import java.util.HashMap;
/**
* @author Alejandro Revilla
*/
public class State {
String name;
String selector;
Map state;
Map action;
public State (String name) {
super ();
this.name = name;
this.state = new HashMap ();
this.action = new HashMap ();
}
public String getName () {
return name;
}
public boolean equals (Object obj) {
if (name == null)
return false;
return name.equals (obj);
}
public void addTransition (String t, String s, String a) {
state.put (t, s);
if (a != null)
action.put (t, a);
}
public String getNext (String t) {
if (t == null)
return this.getName();
return (String) state.get (t);
}
public String getAction (String t) {
if (t == null)
return null;
return (String) action.get (t);
}
public void setSelector (String selector) {
this.selector = selector;
}
public String getSelector () {
return selector;
}
}
// StateMachine
/*
* Copyright (c) 2004 jPOS.org
*
* See terms of license at http://jpos.org/license.html
*
*/
package org.jpos.fsm;
import org.jpos.util.Log;
/**
* @author Alejandro Revilla
*/
public class StateMachine {
Model model;
State current;
Log log;
public StateMachine (Model model) {
super ();
this.model = model;
current = model.getInitialState ();
}
public State getCurrent () {
return current;
}
public void setLog (Log log) {
this.log = log;
}
public String event (String s) {
StringBuffer sb = new StringBuffer ();
String info = current.getName() + " --> " + s;
String next = current.getNext (s);
String action = current.getAction (s);
if (next == null || "nil".equals (next)) {
next = "invalid-transition";
}
State state = model.getState (next);
if (state == null) {
throw new IllegalArgumentException (
"Invalid transition: " +info + " " + next
);
}
if (log != null) {
sb.append (info);
sb.append (" -> ");
sb.append (next);
if (action != null) {
sb.append (" (");
sb.append (action);
sb.append (')');
}
log.info (sb.toString());
}
current = state;
return action;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment