I am creating a Java Client to print messages with a small state-machine at the heart of my main class. This client polls a JMS queue and decides if it needs to print a message from a queue or needs to send a message back with JMS.
I was wondering if you Java gurus would share your state-machine advise for this example.
- I want to keep my state machine in the main class, but want to move all other methods to other classes.
- Should I keep track of my objects (config, message) as static fields?
- Is this a good idea?
This is What I got.
State Diagram:
Main Class:
public class StateMachine {
private static State state;
private static Properties config;
private static Message message;
public static void main(String[] args) throws Exception {
// Finite State Machine
state = State.START;
while (state != State.STOP) {
switch (state) {
case START:
start();
break;
case INITIALIZE:
initialize();
break;
case CONFIG:
config();
break;
case POLLING:
polling();
break;
case PUSH:
push();
break;
case MESSAGE:
message();
break;
case PRINT:
print();
break;
case STOP:
polling();
break;
default:
stop();
break;
}
}
System.exit(0);
}
private static void start() {
// The Client is started: move to initialization phase.
state = State.INITIALIZE;
}
private static void initialize() {
// Currently nothing - Go directory to configuration
state = State.CONFIG;
}
private static void config() {
// Get the configuration
config = PropertyManager.readConfiguration();
String task = config.getProperty("task");
if (task.equals("polling")) {
state = State.POLLING;
} else {
state = State.PUSH;
}
}
private static void polling() {
// Start polling until a message arrives
try {
...
//Implementation that polls a JMQ queue
...
//Break when message arrives
while (true) {
message = consumer.receiveNoWait();
break;
}
session.close();
connection.close();
} catch (Exception ex) {
LOGGER.error(" - {}", ex.toString());
}
state = State.MESSAGE;
}
private static void push() {
// Push a message to the queue
...
// Start polling again
state = State.POLLING;
}
private static void message() {
// Decides what to do after a message is arrived
....
// Currenty, print all messages
state = State.PRINT;
}
private static void print() {
// Print the message
if (message instanceof TextMessage) {
... print ...
}
// Move back to polling after a print.
state = State.POLLING;
}
private static void stop() {
// Go to the STOP state.
state = State.STOP;
}
}