SCXML cheat-sheet

First of all, the tutorial on the SCXML Commons Wiki are a very good start, particularly for the things which are specific to this implementation.

The rest of this document is a collection of things that aren't terribly well documented (or at least where docs are hard to find).

Variation from current SCXML draft

We use the Apache Commons SCXML engine which implements a previous draft of the spec. Here are the differences that I know of:
  • It uses JEXL as its condition language, not XPath. There are two extensions functions to support Statechart functionality:
    • In The Statement "In('statename')" is true when the named is being held
    • Data If you have a datamodel with nested values, the Data function access it. The first argument is the name of the datamodel variable, and the second argument is an XPath within the XML data.
    • If you have a non-nested datamodel (e.g. "<data name="foo" expr="23"/>), then the name becomes a variable directly and "Data" is no necessary
  • The invoke tag uses the targettype attribute in place if the type attribute
  • In a send the event attribute is a JEXL expression. If you just want to send a string event, use single quotes ('' ) to enclose the name
    • Same for the delay attribute
    • eventid is just a string, though
  • content is not supported

General hints

  • There is a useful log tag which can be used in the onentry and onexit blocks to log some data and print out where you are.
  • I found it useful to structure my state-charts into parallel states, where one (hierarchical) state prescribes the sequence of tasks to be executed, and the parallel states are responsible for carrying out one particular sub-task. Just my approach, though, YMMV.

Datamapper instance access

As explained before, you can have your types converted to a FlatTree using the datamapper API in the event input configuration. The values are then available through the _eventdata variable. For example

<transition event="Cards" target="Setup.Done" 
                            cond="_eventdata['cards.count.all'].asInteger() eq TotalCards"/>

checks whether the "cards.count.all" attribute has the same value as the "TotalCards" datamodel variable. Please note that there is also an "asInteger()" call after the attribute access: The SCXML engine simply calls "get" on the FlatTree, which returns a TypedValue instance. If you don't call asSomething, it will be converted using toString, which results in many different things, but not simply value of the attribute.