blob: d3ba60945354b213cdce60f3ae94ce12a6ec7ca7 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<document>
<properties>
<title>Commons SCXML Usage - Five minute SCXML tutorial</title>
<author email="dev@commons.apache.org">Commons Documentation Team</author>
</properties>
<body>
<section name="What is SCXML?">
<p>State Chart XML (SCXML) is a general-purpose event-based state
machine language that can be used in many ways.</p>
<p>The definitive guide to authoring SCXML documents is the
<a href="http://www.w3.org/TR/scxml/">W3C Working Draft
of the SCXML specification</a>.</p>
</section>
<section name="Contents">
<p>This document contains the following sections:
<ul>
<li><a href="#hello">Hello World</a></li>
<li><a href="#transitions">Transitions</a></li>
<li><a href="#composite">Composite states</a></li>
<li><a href="#parallel">Parallel</a></li>
<li><a href="#custom">Hello World with a custom action</a></li>
</ul>
</p>
<a name="hello"/>
</section>
<section name="Hello World">
<p>Here is the canonical
<a href="http://svn.apache.org/repos/asf/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/hello-world.xml">hello world example</a>
for SCXML. The interesting bits are:</p>
<pre>
&lt;scxml xmlns="http://www.w3.org/2005/07/scxml"
version="1.0"
initialstate="hello"&gt;
&lt;state id="hello" final="true"&gt;
&lt;onentry&gt;
&lt;log expr="'hello world'" /&gt;
&lt;/onentry&gt;
&lt;/state&gt;
&lt;/scxml&gt;
</pre>
<p>
<ul>
<li>The document declares an initial state of "hello", which is the entry
point into the state machine.
</li>
<li>Once the state "hello" is entered the "executable content" contained
in the &lt;onentry&gt; is immediately executed.
</li>
<li>Similarly, there is also the symmetric &lt;onexit&gt;, which holds
executable content to be executed when a state is being exited.</li>
<li>The final attribute on state "hello" indicates that the state
machine has "run to completion".</li>
<li>Executable content is made of a series of "actions".</li>
<li>The "standard actions" defined by the SCXML specification are:
&lt;var&gt;, &lt;assign&gt;, &lt;log&gt;, &lt;send&gt;,
&lt;cancel&gt;, &lt;if&gt;, &lt;elseif&gt;, &lt;else&gt;.</li>
</ul>
</p>
<a name="transitions"/>
</section>
<section name="Transitions">
<p>Transitions allow the state machine to change state. A transition is
"followed" if its "trigger event" is received, and the
"guard condition", if one is available is valid.
</p>
<p>Here are some transition variants:</p>
<pre>
&lt;!--
... begin scxml, some states ...
--&gt;
&lt;state id="foo1"&gt;
&lt;!--
... some content ...
--&gt;
&lt;transition target="bar" /&gt;
&lt;/state&gt;
&lt;state id="foo2"&gt;
&lt;!--
... some content ...
--&gt;
&lt;transition event="foo.bar" target="bar" /&gt;
&lt;/state&gt;
&lt;state id="foo3"&gt;
&lt;!--
... some content ...
--&gt;
&lt;transition event="foo.bar" cond="some-boolean-expression"
target next="bar" /&gt;
&lt;/state&gt;
&lt;state id="bar"&gt;
&lt;!--
... some content ...
--&gt;
&lt;/state&gt;
&lt;!--
... remaining states, end scxml ...
--&gt;
</pre>
<p>
<ul>
<li>The first transition in document order is an "immediate"
transition. "foo1" is the source, and "bar" is the
destination (transition target).
</li>
<li>The second transition waits for the trigger event "foo.bar".
</li>
<li>The third waits for "foo.bar" and the guard condition
specified by its "cond" attribute to evaluate to true
the instant the event is received.
</li>
</ul>
</p>
<a name="composite"/>
</section>
<section name="Composite states">
<p>States can contain states, so we can think of an
SCXML document as a recursive transition network. Here is
a snippet (here is the entire version of this
<a href="http://svn.apache.org/repos/asf/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/microwave-01.xml">microwave example</a>
):</p>
<pre>
&lt;!--
... begin snippet ...
--&gt;
&lt;state id="on"&gt;
&lt;initial&gt;
&lt;transition target="idle"/&gt;
&lt;/initial&gt;
&lt;state id="idle"&gt;
&lt;!-- content for state "idle" --&gt;
&lt;/state&gt;
&lt;state id="cooking"&gt;
&lt;!-- content for state "cooking" --&gt;
&lt;/state&gt;
&lt;!-- other content for state "on" --&gt;
&lt;!--
... end snippet ...
--&gt;
</pre>
<p>
<ul>
<li>The state "on" is an example of a composite state.</li>
<li>It contains two states, "idle" and "cooking". Since
there are no other sibling states, this means that when the
microwave is turned on, it must be in either idle or cooking
state.
</li>
<li>Since there are multiple states in the state "on", an
&lt;initial&gt; element is required. This becomes the "active"
child state when a transition is made to the composite state.
(in this case, a transition to state "on", causes the "idle"
state to be active).
</li>
<li>States can be recursively nested to any depth.</li>
</ul>
</p>
<a name="parallel"/>
</section>
<section name="Parallel">
<p>This is a wrapper element that encapsulates multiple
&lt;state&gt;s -- or state machines, since in the section on
composite states we took a look at the "recursion" or
"nesting" for the &lt;state&gt; element, whereby each state
can become a state machine in its own right -- that are "active"
at the same time. Here is
a relevant snippet (the entire version of this
<a href="http://svn.apache.org/repos/asf/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/microwave-02.xml">parallel microwave example</a>
):</p>
<pre>
&lt;!--
... begin snippet ...
--&gt;
&lt;state id="microwave"&gt;
&lt;parallel id="parts"&gt;
&lt;state id="oven"&gt;
&lt;!-- state machine for "oven" (idle/cooking) --&gt;
&lt;/state&gt;
&lt;state id="door"&gt;
&lt;!-- state machine for "door" (open/closed) --&gt;
&lt;/state&gt;
&lt;/parallel&gt;
&lt;/state&gt;
&lt;!--
... end snippet ...
--&gt;
</pre>
<p>
<ul>
<li>The state "microwave" is an example of a "orthogonal"
state (one that owns a parallel).</li>
<li>It contains two state machines, "oven" and "door". These
state machines are "active" at the same time. These are
known as "regions".
</li>
<li>Transition may occur within a region or from a region to
outside the &lt;parallel&gt; (see below), but never from
one region to another ("across" regions).
</li>
<li>There is no need for an &lt;initial&gt; element within
a &lt;parallel&gt;</li>
<li>The state machine must enter all regions at the same time,
and an outbound transition out of the &lt;parallel&gt;
from any region causes the state machine to exit all
regions.</li>
<li>When all regions reach a "final" state, an "id.done" event
is fired, where "id" is the id of the parent &lt;parallel&gt;
</li>
</ul>
</p>
<a name="custom"/>
</section>
<section name="Hello World with a custom action">
<p>The Commons SCXML implementation allows you to register custom actions.
Here is the Commons SCXML
<a href="http://svn.apache.org/repos/asf/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/custom-hello-world-02.xml">hello world example using a custom action</a>.
The interesting bits are:</p>
<pre>
&lt;scxml xmlns="http://www.w3.org/2005/07/scxml"
xmlns:my="http://my.custom-actions.domain/CUSTOM"
version="1.0"
initialstate="custom"&gt;
&lt;state id="custom" final="true"&gt;
&lt;onentry&gt;
&lt;my:hello name="world" /&gt;
&lt;/onentry&gt;
&lt;/state&gt;
&lt;/scxml&gt;
</pre>
<p>
<ul>
<li>&lt;my:hello&gt; is an example of a custom action whose local
name is "hello" and is bound to the fictitious namespace
"http://my.custom-actions.domain/CUSTOM"
</li>
<li>The custom action hello merely logs a hello to the value of
the name attribute, and thus the above example produces results
identical to the initial hello world example above.
</li>
<li>For details, see the section on
<a href="custom-actions.html">custom actions</a> in this guide.
</li>
</ul>
</p>
</section>
</body>
</document>