Bgrenon
Contents
SCXML Language Reference <test page>
Click here to view the organization and contents of the SCXML Language Reference.
SCXML stands for State Chart XML: State Machine Notation for Control Abstraction. Orchestration Server utilizes an internally developed SCXML engine which is based on, and supports the specifications outlined in the W3C Working Draft 7 May 2009 [1]. There are, however, certain changes and/or notable differences (see Extensions and Deviations) between the W3C specification and the implementation in Orchestration Server which are described on this page. Only the ECMAScript profile is supported (the minimal and XPath profiles are not supported).
Usage
SCXML documents are a means of defining control behaviour through the design of state machines. The SCXML engine supports a variety of control flow elements as well as methods to manipulate and send/receive data, thus enabling users to create complex mechanisms.
For example, Orchestration, which is a consumer of the SCXML engine, uses SCXML documents to execute strategies. A simple strategy may involve defining different call routing behaviours depending on the incoming caller, however, the SCXML engine facilitates a wide variety of applications beyond simple call routing.
Authoring SCXML documents can be done using any text editor or by leveraging the Genesys Composer tool.
Syntax and Semantics
The appearance of an SCXML document is very similar to that of any other markup language. The use of various SCXML-specific tags define the structure and operation of a state machine. The SCXML snippet below illustrates how an SCXML document may look like in structure:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Specifying the encoding is important! -->
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml"
name="SCXML DOCUMENT NAME" >
<initial>
<transition target="FIRST_STATE">
<log expr="'Inside the initial transition'" />
</transition>
</initial>
<state id="FIRST_STATE">
<onentry>
<log expr="'Do things here when state is first entered'" />
<send event="LEAVE_STATE" />
</onentry>
<onexit>
<log expr="'Do things here when state is being exited'" />
</onexit>
<transition event="LEAVE_STATE" target="exit">
<script>
var message = 'Do things here during a transition';
</script>
<log expr="message" />
</transition>
</state>
<final id="exit" />
</scxml><span class="re1"><?xml</span> <span class="re0">version</span>=<span class="st0">"1.0"</span> <span class="re0">encoding</span>=<span class="st0">"UTF-8"</span><span class="re2">?></span><span class="co1"><!-- Specifying the encoding is important! --></span><span class="re1"><scxml</span> <span class="re0">version</span>=<span class="st0">"1.0"</span> <span class="re0">xmlns</span>=<span class="st0">"http://www.w3.org/2005/07/scxml"</span> <span class="re0">name</span>=<span class="st0">"SCXML DOCUMENT NAME"</span> <span class="re2">></span> <span class="re1"><initial<span class="re2">></span></span> <span class="re1"><transition</span> <span class="re0">target</span>=<span class="st0">"FIRST_STATE"</span><span class="re2">></span> <span class="re1"><log</span> <span class="re0">expr</span>=<span class="st0">"'Inside the initial transition'"</span> <span class="re2">/></span> <span class="re1"></transition<span class="re2">></span></span> <span class="re1"></initial<span class="re2">></span></span> <span class="re1"><state</span> <span class="re0">id</span>=<span class="st0">"FIRST_STATE"</span><span class="re2">></span> <span class="re1"><onentry<span class="re2">></span></span> <span class="re1"><log</span> <span class="re0">expr</span>=<span class="st0">"'Do things here when state is first entered'"</span> <span class="re2">/></span> <span class="re1"><send</span> <span class="re0">event</span>=<span class="st0">"LEAVE_STATE"</span> <span class="re2">/></span> <span class="re1"></onentry<span class="re2">></span></span> <span class="re1"><onexit<span class="re2">></span></span> <span class="re1"><log</span> <span class="re0">expr</span>=<span class="st0">"'Do things here when state is being exited'"</span> <span class="re2">/></span> <span class="re1"></onexit<span class="re2">></span></span> <span class="re1"><transition</span> <span class="re0">event</span>=<span class="st0">"LEAVE_STATE"</span> <span class="re0">target</span>=<span class="st0">"exit"</span><span class="re2">></span> <span class="re1"><script<span class="re2">></span></span><span class="co3"> var message = 'Do things here during a transition'; </span><span class="re1"></script<span class="re2">></span></span> <span class="re1"><log</span> <span class="re0">expr</span>=<span class="st0">"message"</span> <span class="re2">/></span> <span class="re1"></transition<span class="re2">></span></span> <span class="re1"></state<span class="re2">></span></span> <span class="re1"><final</span> <span class="re0">id</span>=<span class="st0">"exit"</span> <span class="re2">/></span><span class="re1"></scxml<span class="re2">></span></span>
Basic Elements
SCXML elements for defining states, transitions, and behavior include (but are not limited to):
- <state>
- <transition>
- <parallel>
- <initial>
- <final>
- <onentry>
- <onexit>
In addition, it is also possible to define actions which are performed during state transitions (<onentry>, <onexit>, within <transition>) by using the following Executable Content elements (but are not limited to):
- <if>/<elseif>/<else>
- <foreach> (planned feature) already implmented, not just planned (see below)?
- <raise>
- <log>
It is also possible to embed script code (ECMAScript) within the state machine by using the following element:
- <script>
One may refer to the W3C Working Draft [2] for more detailed explanations of the above elements and basic usage examples.
Managing Data
SCXML applications are commonly driven by data acquisition and manipulation, where the data gathered can be processed to determine application behaviour. Users may define data models within an SCXML document by using the <datamodel> element. A <datamodel> element may have any number of elements as seen below:
<datamodel> <data id="target" expr="'Hello World!'"> <data id="this_is_one" expr="1"> <data id="m_array" expr="['a', 'b', 'c']"></data></data></data></datamodel>
Any data objects defined in this manner become accessible as a child of the _data global object. To access a data object defined within a <datamodel>, the following syntax is used:
_data.data_ID // Where data_ID is replaced by the ID of the data element
Alternatively, one may opt to declare data objects/variables within a <script> block instead if more complex initialization routines are required. Variables defined within a <script> block, however, become children of the <script> element's parent's local scope. That is, if it was defined in the global scope (<scxml>), the variables will be globally accessible; if it was defined within a state, the variables will become children of the state's local scope.
<script> var target='Hello World!'; var this_is_one=1; var m_array = ['a', 'b', 'c'];</script><log expr="'The value of target is: ' + target"></log>
Data sharing between SCXML sessions
It may be desirable in many situations to be able to share data between multiple SCXML sessions. Data may be shared between sessions using the following methods:
Session Initiated
- When one SCXML session initiates another SCXML session via the <invoke> action (or <session:start>, <session:fetch>, which are specific to Orchestration only!) the initiating session can share data via the model defined in the SCXML specification. The
element is used to create an instance of an external service. This implementation differs from the W3C specification in that the SCXML engine does not support thetypeexpr, srcexpr,andnamelistattirbutes, and thechild element.
| Name | Required | Type | Default Value | Valid Value | Description |
| type | false | URI | "scxml" | "scxml" (equivalent to “http://www.w3.org/TR/scxml/”) | Type of the external service. |
| src | false | URI | none | Any URI | A URI to be passed to the external service. |
| id | false | ID | none | Any valid token | A string literal to be used as the identifier for this instance of . |
| idlocation | false | Location Expression | none | Any valid location expression | Any data model expression evaluating to a data model location. |
| autoforward | false | Boolean | false | true or false | A flag indicating whether to forward events to the invoked process. |
For more details, see the implementation" contenteditable="false" href="http://www.w3.org/TR/scxml/#invoke" data-mce-href="http://www.w3.org/TR/scxml/#invoke" data-bs-type="external_link" data-bs-wikitext="http://www.w3.org/TR/scxml/#invoke implementation"> implementation section on the W3C website.
Session runtime
- During the execution of a session, a session can shared data with another session via events and the <send> action.
Events
Event handling (both internal and external) is fully supported by the SCXML engine. The event model allows users to control SCXML sessions by sending events from external entities or by raising events internally during the execution of an SCXML document. These events can be used to drive transitions or send data to external systems.
Internal Events
These events are published and consumed by the same SCXML session. The following are the methods of managing them:
Publish
- To generate an event, either the <event> or <send> element can be used. The SCXML engine puts the event into the session's event queue. When using <send>, it is possible to place the event on either the external event queue or internal event queue, based on the value of the target attribute. (If the special value '
_internal' is specified, the event is added to the internal event queue of the current session. If no value is specified, the event is added to the external event queue of the current session.). When using <send> to generate events, if there is an intention to cancel the event sent, it is recommended to use the attributeidlocationinstead ofid.
Subscribe
- Receiving events is achieved by using the <transition> element. If the event contains properties, one may access the event's properties via the
_eventsystem variable:
_event.data
The Orchestration platform supports the use of wildcards ("*") when evaluating event names.
External Events
These events are published and consumed by the given SCXML session and the corresponding external entity. The following is a list of external entities that are supported:
- Other SCXML sessions
- External systems via Functional Modules
- External applications
The following are the methods of managing events from an SCXML-session standpoint:
Publish
- The <send> element with the appropriate
targettypeattribute value:- scxml - for other SCXML sessions. Events may be delivered to the appropriate session within the same platform server or across platforms, and is facilitated by the message functionality of the platform. The
targetattribute has the following format:url#sessionid - basichttp - for external applications. These events are delivered to the appropriate external application, based on the defined target URL and an HTTP POST message.
- fm - for any Functional Module-related systems. The
targetattribute is the functional module's namespace name.In addition to the <send> element, a given Functional Module may have an action element to send events, as well.
- scxml - for other SCXML sessions. Events may be delivered to the appropriate session within the same platform server or across platforms, and is facilitated by the message functionality of the platform. The
Subscribe
- The <transition> element. If the event contains properties, one may access the event's properties via the
_eventsystem variable:
_event.data: In general, overall external event subscription is implicit:
- Functional Modules - No content here?
- External applications and other SCXML sessions - When these events are sent, they are sent explicitly to the given session (by session ID), so no explicit subscription is needed.
The following are the methods of managing events from an external system standpoint:
Publish
- The method depends on the source of the event:
- Other SCXML sessions - The <send> element is used.
- External applications - The platform external interface is used (SendTransitionEvent). The platform has the appropriate functionality to receive events from external sources and deliver them to the appropriate sessions.
- Functional Modules - The Functional Module sends the events to the platform based on the defined Functional Module framework interfaces and the platform then delivers the events to the appropriate session event queue.
Subscribe
- For any of the potential subscribers, there is no explicit subscription method, because the SCXML session is targeting a specific destination when publishing the event, so the destination must have the appropriate interface to receive the event.
- Functional Modules - The Functional Module supports the appropriate functional module framework interface to receive the events from the session.
- External applications have the appropriate web application to process the HTTP post.
- Other SCXML sessions receive the event on their event queues via the platform.
Common Properties for Internal and External Events
The following common properties are present in all events, whether internal or external:
name- This is a character string giving the name of the event. It is what is matched against the 'event' attribute of <transition>. Note that transitions can carry out additional tests by using the value of this field inside boolean expressions in the 'cond' attribute.type- This field describes the event type. It MUST contain one of an enumerated set of string values consisting of: "platform" (for events raised by the platform itself, such as error events), "internal" (for events raised by <event>), and "external" (for all other events, including those that the state machine sends to itself via <send>).sendid- In the case of error events triggered by a failed attempt to send an event, this field contains the sendid or id of the triggering <send> element. Otherwise it is blank.invokeid- If this event is generated from an invoked child process, this field contains the invokeid of the invocation (<invoke invokeid="..." or id="...">) that triggered the child process or in the case of error events triggered by a failed attempt to invoke another process, this field contains the invokeid or id of the invoking <invoke> element. Otherwise it is blank.
The following fields are logically present in all events, but are filled in only in external events:
origin- This a URL, equivalent to the 'target' attribute on the <send> element. The combination of this field with the 'origintype' field SHOULD allow the receiver of the event to <send> a response back to the entity that originated this event. Not currently supported.origintype- This is a character string, similar to the 'targettype' or 'type" attribute in <send>. The combination of this field with the 'origin' field SHOULD allow the receiver of the event to <send> a response back to the entity that originated this event. Not currently supported.data- This field contains whatever data the sending entity chose to include in this event. The receiving platform SHOULD reformat this data to match its data model, but MUST not otherwise modify it.
Extensions and Deviations
The Genesys SCXML implementation introduces various additions and differences from the W3C SCXML specifications. The following extensions and deviations were introduced to accommodate the needs of the SCXML engine.
ECMAScript
SpiderMonkey 1.7 is used as the ECMAScript engine. It implements a superset of ECMA-262 Edition 3. This allows for the inclusion of scripts within SCXML documents when more advanced computational logic is required beyond the standard SCXML elements.
System Variables
The SCXML specification defines the following system variables which may provide useful information to applications (all of which are available in the global scope):
_sessionid
- This represents the unique ID associated with this SCXML session. It is set by the platform.
_name
- This represents the name that the developer gives this particular SCXML document (for example, "Mortgage Process Logic". It is set by the developer when creating the document.
_event
- This represents the event being presented to the application. It is set by the platform when the event is available to the application.
_type
- This represents the type of application that the developer gives this particular SCXML document (that is, <SCXML> element
_typeattribute). It is set by the developer when creating the document.
In addition to the above variables, the SCXML engine also provides the following extension system variables:
_parentSessionid
- This represents the unique ID associated with the parent of this SCXML session. If the session has no parent, the value returned is an empty string. It is set by the platform.
_genesys
- This is the root object for accessing all Genesys-specific ECMAScript objects and functions. Note that the user is not allowed to set properties in _genesys as it is a protected system object. See Orchestration Extensions for more information.
_data (<datamodel>)
- These are the objects that are created based on the datamodels defined within the SCXML document. For example, data to be used during the processing of the logic and expected initiation and return parameters for the session. See the _data (ORS Extensions) section below for Orchestration-specific properties of the datamodel.
Protected Variables
Variables may be defined and set on any scope except within _genesys. In addition, top-level variables starting with '_' are considered system variables and should not be modified. Defining top-level variables with names starting with an underscore '_' is prohibited. However, the same restriction does not apply if the variable is defined under a top level property such as the datamodel.
_data (ORS extensions)
In addition to storing session start parameters and user-defined datamodel items, the _data object may sometimes be used by Orchestration to provide extra information about the session.
ℭ|! Property Name>
| Description | --> | -| _data.server| |-| _data.application| |-| _data.provision_type| |-| _data.provision_value| |-| _data.tenant_id| |-| _data.timestamp| |-| _data.document_hash| " contenteditable="false" data-bs-type="comment" data-bs-id="0" data-bs-wikitext="" contenteditable="false">ℭhello is not defined. Line 1 - in <script> at line: 117" thread="8596"></exec_error>
An uneval of the session datamodel post-recovery might indicate the variables declared within the state have all been persisted:
<br class="bs_emptyline">__my_state__:{ scope:”my_state”, hello:”hello world!”, fun:(function () {__Log(scope + “: “ + hello);}) } <!--|-| _data.server| |-| _data.application| |-| _data.provision_type| |-| _data.provision_value| |-| _data.tenant_id| |-| _data.timestamp| |-| _data.document_hash| -->
The key difference between pre-recovery and post-recovery is that now, the function <scxml initial=”my_state”>
...
<script>
// This is a top-level script block
var scope = “global”;
</script>
<state id=”my_state”>
<onentry>
<script>
var scope = “my_state”;
var fun = function(){
__Log(scope);
}
<script>
</onentry>
<transition event=”show_message”>
<script>
fun();
</script>
</transition>
</state>
...With the above code, One possible solution would be to design the function as follows: <scxml initial=”my_state”>
...
<script>
// This is a top-level script block
var scope = “global”;
</script>
<state id=”my_state”>
<onentry>
<script>
var scope = “my_state”;
var hello = “hello world!”;
var fun = function(self){
__Log(self.scope + “: “ + self.hello);
}
</script>
</onentry>
<transition event=”show_message”>
<script>
fun(this);
</script>
</transition>
</state>
...By passing in a reference to Object OwnershipObjects and its associated properties are not implicitly shared with other sessions or external applications, but there are methods to explicitly share these objects and properties with other sessions and applications. A session can only share snapshots of the current properties and objects - they are not updated dynamically when the owning session changes them. The following are the methods of how content can be shared:
FunctionsThe session has access to system functions (time, date, and so on) through the standard ECMAScript objects and functions. In addition to the core ECMAScript script functions, the SCXML engine exposes some other useful functions. E4X (ECMAScript for XML)SpiderMonkey supports E4X, which adds native XML support to ECMAScript. This allows the user to access XML data as primitives, rather than as objects. See the following example for usage: var sales = <sales vendor="John">
<item type="peas" price="4" quantity="6"/>
<item type="carrot" price="3" quantity="10"/>
<item type="chips" price="5" quantity="3"/>
</sales>;
alert( sales.item.(@type == "carrot").@quantity );
alert( sales.@vendor );
for each( var price in sales..@price ) {
alert( price );
}
delete sales.item[0];
sales.item += <item type="oranges" price="4"/>;
sales.item.(@type == "oranges").@quantity = 4;JSONThe following functions provide a convenient method of serializing and deserializing data to and from the JavaScript Object Notation (JSON) format:
__GetDocumentURLReturns the URL of the currently running scxml strategy. Usage: __GetDocumentURL() Parameters:
__GetDocumentBaseURLReturns the base URL of the currently running scxml strategy. Usage: __GetDocumentBaseURL() Parameters:
__LogThis function is the ECMAScript equivalent to the <log> element. It allows an application to generate a logging or debug message which a developer can use to help in application development or post-execution analysis of application performance. Usage: __Log (expr) or __Log(expr, label, level) Parameters:
__RaiseThis function is the ECMAScript equivalent to the <raise> element. It allows an application to raise an event which can be used to direct the execution flow of an SCXML strategy. Usage:
__GetDocumentTypeReturns the document type of the currently running scxml strategy. The value returned is equivalent to the value of the _type attribute of the <SCXML> element, as specified by the developer. Usage: __GetDocumentType() Parameters:
__GetCurrentStatesReturns an array of strings containing names of the currently active states. Usage: __GetCurrentStates() Parameters:
__GetQueuedEventsReturns an array of strings containing events currently placed into the event queue. Usage: __GetQueuedEvents() Parameters:
InDetermines if the state specified is currently active. If so, returns true, otherwise returns false. Usage: In( "example_state_name" ); Parameters:
Function ScopingA caveat resulting from the Variable Scoping deviation is that developers must now be aware of the scope in which his/her functions execute. User-defined functions will generally execute in the local scope where they were defined. This means that any variables referenced within a user-defined function must also exist within that very same scope. It is possible to invoke a function outside of its native scope (e.g. by referencing another state directly through the object model, or by referencing a function that was defined in a parent state), but note that its variable scoping will remain in that native scope (where the function was defined). See example below: <state id="outer" initial="inner">
<onentry>
<script>
var scope="outer";
var foo=function(){__Log("foo finds scope: " + scope);}
</script>
</onentry>
<state id="inner">
<onentry>
<script>
var scope="inner";
var bar=function(){__Log("bar finds scope: " + scope);}
</script>
<script>
foo(); // Outputs --> foo finds scope: outer
bar(); // Outputs --> bar finds scope: inner
</script>
</onentry>
</state>
</state>Note for Orchestration users only: Function scope will not be restored after session recovery! This is a critical difference that must be accounted for when designing an SCXML application to survive fail-over and recovery. Tests have shown that after a session has been restored from persistence, all user-defined functions (particularly those defined within states will execute in the global scope as opposed to their original native scope. To address this issue, it is highly recommended that developers explicitly specify the scope of their variables rather than use implicit scoping. See example below: <state id="outer" initial="inner">
<onentry>
<script>
var scope="outer";
var implicit=function(){__Log("implicit finds scope: " + scope);}
var explicit=function(self){__Log("explicit finds scope: " + self.scope);}
</script>
</onentry>
<state id="inner">
<onentry>
<script>
var scope="inner";
</script>
<script>
implicit(); // Outputs --> implicit finds scope: outer
explicit(this); // Outputs --> explicit finds scope: inner
explicit(<span id="bs_switch:@@@SWT1@@@" class="mceNonEditable wikimagic switch" title="__outer__" data-bs-type="switch" data-bs-id="1" data-bs-name="outer" data-bs-wikitext="__outer__" contenteditable="false">§</span>); // Outputs --> explicit finds scope: outer
</script>
</onentry>
</state>
</state>SCXML Elements<anchor>The <anchor> module is not supported by the SCXML engine. This element would otherwise be used for providing 'go back' or 'redo'-like functionality for applications. <cancel >For <cancel>, either one of the attributes When using <send> to generate events, if there is an intention to cancel the event sent, it is recommended to use the attribute When the <cancel> request has been processed, the SCXML engine will send back the "cancel.successful" event if the event was successfully removed, or "error.notallowed" if there was a problem, along with the attribute The following are the additional Genesys attributes for element. They are strictly used to help define and administer the provisioning of this data from the appropriate source. Attribute Details
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
