SCXML

From Model-based User Interfaces Incubator Group Wiki
Jump to: navigation, search

State Chart XML (SCXML) is a general-purpose, event-based control language originally desgined for usage in voice and multimedia applications. It combines concepts from CCXML with David Harel's Statecharts, an extension to final state machines.

Language description

The last W3C Working Draft from 16 May 2008 breaks the langauge specification down into several modules according to provided functionality:

  • Core module: elements of a basic Harel state machine: <state>, <parallel>, <transition> etc.
  • External communication module: means of external event exchange: <send> and <invoke>
  • Script module: support for ECMAScript implementation of executable content
  • Data module: abstract <datamodel> containing named parts
  • Anchor module: provides 'redo' functionality via <datamodel> snapshots

Several abstract expression langauges are identified in order to support this functionlity:

  • Conditional Expressions are boolean expressions used in condition evaluation (@cond)
  • Location expressions are path expressions used to locate parts of the datamodel
  • Legal Data Values and Value Expressions specify the data structure (XML, JSON) implmenting the datamodel and valid expressions applied to it

Finally language profiles specify module subsets and implementations for expression langauges a profile conformant interpreter needs to support:

  • Minimal Profile: Core module
  • ECMAScript Profile: Core, Script and Data modules (JSON, ECMAScript scope chain)
  • XPath profile: Core and Data module (XML with XPath)

General concepts

Executable Content

  • actions performed on transitions, entering and leaving states
  • execute instantaneously (in opposite to an activity)
    • emmiting events (<event>, <send>)
    • branching on conditions (<if>, <else>, <elseif>)
    • script execution (<script>)
    • updates on data model (<assign>)
    • logging (<log>)
     <!-- assign the process owner to user triggering the "start" event -->
     <transition event="start" target="main">
       <assign location="$ownerId" expr="$_eventdata/payload/context/userId" />
     </transition>
  • custom actions are calls to an external implementation via registered tags

Example using Apache Commons SCXML: the custom action class PublishAction extends the Action class. It is registered with the SCXMLParser. A new instance is created and the inherited Action#execute method is called whenever the tag is processed:

 customActions.add(new CustomAction("urn:myactions, "publish", PublishAction.class)); 
 <scxml xmlns:ui="urn:myactions" xmlns="http://www.w3.org/2005/07/scxml" initial="initial" version="1.0">
  <state id="collectData">
   <onentry><ui:publish/></onentry>
   ...
  </state>

State

A state represents an unique position within the state machine.

  • it is either atomic (<state>) or complex
  • complex states decompose either to:
    • mutually exclusive sub states (XOR decomposition) within a <state> container
    • initial sub state definied via @initial or <initial>
      • sub states are activated according to generated event sequence and data conditions (c.f. explicit dependency statement via @requires and step order in ANSI/CEA-2018)
    • simultaneously active sub states (AND decomposition) within a <parallel> container
      • modelling of orthogonal dimensions and characteristics
      • respective substates are independent, but could by synchronized via common events or a shared datmodel
  • encapsulates an informational state (<datamodel>) and behaviour (<invoke> and executable content within <transition>, <onentry> and <onexit>)
  • a <history> sub state stores the current status for later recovery (pause/resume functionality)
  • has no explicit data interface (cf. input and output slots in ANSI/CEA-2018)
<-- example of a parallel state with orthogonal "selection" and "adaption" aspects of the content -->
    <parallel id="content">    
     <state id="selection"> 
       ...
     </state>
     
     <state id="adaption">
       <state id="ready">
         <transition cond="count($adaptations/adaptationList/adaptation[@status!='done']) > 0" target="ongoing"/>          
         <transition event="end" target="end"/>
       </state>
       <state id="ongoing">          
         <transition cond="count($adaptations/adaptationList/adaptation[@status!='done']) = 0" target="ready"/>
       </state>                
     </state>      
     
   </parallel>

Event

Events are immutable messages and the preferred means of communication between states and the environment.

  • structured and wildcarded event names for selective matching:
     <transition event="input.*" />
     <transition event="input.gui" .. />
     <transition event="input.voice" .. /> 
   
  • internal and external event queues (external processed when internal queue empty)
  • allows for arbitrary data payload according to the data model implementation
    • available in gurad conditions for further event matching
   <transition event="next" cond="$_event/payload/page = 'editProfile'" target="editProfile"/>
  • has no explicit metadata attached (type, slot name)


Transition

A transition designates a target state and/or an action performed on a specific condition (if any). It has the following signature (with all parts being optional):

  • @event: arbitrarily specific event name (e.g. error.*, error.internal.*)
  • @cond: guard condition upon which the transition is enabled
  • @target: a singular state or multiple descendants of a single <parallel> appointed at design time
  • text content: actions performed when this transition is taken

There is a trade-off between using dedicated "business events" or more generic events localized by an guard condition:

   <transition event="editProfile" target="editProfile"/>
   <transition event="next" cond="$_event/payload/page = 'editProfile'" target="editProfile"/>
  • transitons of ancestor states are inherited (general handler at higher levels)
    • a matching transition is selected in document order within current state (top-down), then in ancestor order (bottom-up)
  <state id="main">
    <transition event="error.*"><log label="generic error handler" expr="$_event/payload/msg"/></transition>
    <state id="collectData">
      <transition event="error.input">...</transition>
    </state>
  </state>


Usage patterns

A targetless transition offers an event handler without the side-effect of leaving the recent state. The data is passed via event payload:

 <transition event="republish"><ui:publish mode="$_event/payload/mode" /></transition>

Handlers are chained via event/transition sequences:

         <transition event="view">      
           <log expr="'this is a summary of global data '"/>                        
           <event name="view.detail"/>
         </transition>
         
         <transition event="view.detail">      
           <log expr="'some additional details'"/>                             
         </transition>

Executable content is used to emit higher level events based on evaluation of incomming low-level events or on a declarative data condition (c.f. xforms:bind/@constraint)

  <transition event="error.*"><assign location="$errors" expr="$errors +1"/></transition>
  <transition cond="count($errors) &gt; 10"><event name="'status.emergency'"/></transition>


Task allocation is controlled via posing access conditions on events. A standardized data model is updated and interpreted at runtime offering the user with an UI with appropriate triggers (cf. dedicated slots "device", "external" in ANSI/CEA-2018)

   <state id="collectCourse">      
     <datamodel>
       <data id="access.view">
         <view xmlns=""><role>student</role></view>
       
       
         <edit xmlns=""><userId>tutor12</userId></edit>
       
       
         <cancel xmlns=""><userId>tutor12</userId></cancel>
       
     </datamodel>
     <onentry><ui:publish/></onentry>
     <transition event="edit" target="edit" />        
     <transition event="cancel">        
        <send event="'delete'" targettype="'x-session-management'" target="sessionId"/>
     </transition>
   </state>

Grounding

There are several ways to "ground" the abstract flow control in order to perform external actions:

custom action

  • part of executable content
  • synchronous, blocking
  • proprietary implementation

<send> is used to deliver events to external targets

  • part of executable content
  • asynchronous, non blocking
  • proprietary signaling (no explicit correlation of request and response message)

<invoke> is used to model a state activity

  • exclusive content of an atomic state
  • asynchronous, non blocking
  • requires external "stateId.done" event to conclude

Links