Tuesday, 6 August 2013

Java - Spring Framework - State Machine

Java - Spring Framework - State Machine

I've been looking at refactoring some should be transactional code into
modules where I can apply the state machine pattern on. Initially, I
created the following classes:
public interface IExecutableState {
public void execute();
}
public class StateMachine {
// final:
private static final Logger LOGGER =
Logger.getLogger(StateMachine.class);
// instance private:
private HashMap<String, State> validStates;
private State currentState;
// getters:
public HashMap<String, State> getValidStates() { return
this.validStates; }
public State getCurrentState() { return this.currentState; }
// setters:
public void setValidStates(HashMap<String, State> validStates) {
// assign the stateMachine attribute to each State from this
setter, so that Spring doesn't enter an infinite loop while
constructing a Prototype scoped StateMachine.
for (State s : validStates.values()) {
// validate that the State is defined with implements
IExecutableState
if (!(s instanceOf IExecutableState)) {
LOGGER.error("State: " + s.toString() + " does not
implement IExecutableState.");
throw new RuntimeException("State: " + s.toString() + "
does not implement IExecutableState.");
}
LOGGER.trace("Setting stateMachine on State: " + s.toString()
+ " to: " + this.toString() + ".");
s.setStateMachine(this);
}
LOGGER.trace("Setting validStates: " + validStates.toString() + ".");
this.validStates = validStates;
}
public void setCurrentState(State currentState) {
if (!(currentState instanceOf IExecutableState)) {
LOGGER.error("State: " + currentState.toString() + " does not
implement IExecutableState.");
throw new RuntimeException("State: " +
currentState.toString() + " does not implement
IExecutableState.");
}
LOGGER.trace("Setting currentState to: " + currentState.toString()
+ ".");
this.currentState = currentState;
}
}
public class State {
private StateMachine;
public StateMachine getStateMachine() { return this.stateMachine; }
public void setStateMacine(StateMachine stateMachine) {
this.stateMachine = stateMachine; }
}
All states would look like: public class <StateName> extends State
implements IExecutableState { ... }.
Then, with this model, I wanted to create a prototype scoped spring bean
to instantiate the stateMachine, and assign it all of the states.
However, after looking at some of the things available in Spring WebFlow,
I started to see WebFlows, which emulate the State Machine behavior I
seek, flawlessly. And, in a manner that allows for a visual representation
of each state flow I create from XML.
The only issue I'm finding, is the WebFlows are meant for Web Projects /
Web Applications / Web Sites (whichever you want to classify them as). I
am looking for something very similar to the <view-state> tags you get in
spring webflow, but for an application that is running in a spring-core,
spring-integration, or spring-batch project.

No comments:

Post a Comment