Statechart Machine Generator

The statechart machine generator prompts the user for the name of an XPD file containing a statechart diagram as well as the name of the diagram. (XPD is the XML language used by StarUML to represent all UML diagrams.) If, for example, the name of the diagram was ATM, then the generator generates a file called ATMContext.java containing:

public class ATMContext extends Context {
   public ATMContext() {
      // generated code for initializing machine goes here
   }
   public static void main(String[] args) {
      Context context = new ATMContext();
      context.controlLoop();
   }
}

Of course the constructor would contain real code. The Context superclass is given by:

public class Context {
  
   protected StatechartMachine machine = new StatechartMachine();
  
   public void controlLoop() {
      Scanner kbd = new Scanner(System.in);
      Thread slave = new Thread(machine);
      machine.setContext(this);
      slave.start();
      while(true) {
         System.out.print("trigger an event -> ");
         String response = kbd.nextLine();
         if (response.equals("quit")) {
            machine.halt();
            break;
         }
         Trigger t = new Trigger(response);
         machine.setTrigger(t);
      }
      System.out.println("bye!");
   }
}

The Design

In order to work, your context depends on the following classes:

From this design we see that a Statechart machine is a special kind of state. Here's a sketch of the run method for State:

void run() {
   execute entry actions
   if (!final) {
      while(true) {
         if (trigger != null) {
            lookup the transition triggered
            check that all of the guards of this transition are true
            execute the effects of this transition
            set the next states of this state to be the next states of the transition
            break;
         }
         execute do actions
         Thread.sleep(20); // be cooperative
      execute exit actions
   }
}

A statechart machine overrides this run method. It perpetually examines its inherited list of next states, only in this case this list represents the current states. Any state that has its nextStates field non-null is assumed to be finished running. It is removed from the list, and its next states are added to the state machine's next states. If the trigger field of a statechart machine is set (from the context), then the trigger field of each next state will be set by the statechart machine.