| <?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>Using custom actions with Commons SCXML</title> |
| <author email="dev@commons.apache.org">Commons Documentation Team</author> |
| </properties> |
| |
| <body> |
| |
| <section name="What is a 'custom action'?"> |
| |
| <p>Actions are SCXML elements that "do" something. Actions can be |
| used where "executable content" is permissible, for example, |
| within <onentry>, <onexit> and <transition> |
| elements.</p> |
| |
| <p>The <a href="http://www.w3.org/TR/scxml/">SCXML specification</a> |
| (currently a Working Draft) defines a set of "standard actions". |
| These include <var>, <assign>, <log>, <send>, |
| <cancel>, <if>, <elseif> and <else>.</p> |
| |
| <p>The specification also allows implementations to define "custom actions" |
| in addition to the standard actions. What such actions "do" is |
| upto the author of these actions, and these are therefore |
| called "custom" since they are tied to a specific implementation |
| of the SCXML specification.</p> |
| |
| </section> |
| |
| <section name="Custom actions with Commons SCXML"> |
| |
| <p>Commons SCXML makes authoring custom actions fairly straightforward.</p> |
| |
| <subsection name="What can be done via a custom action"> |
| |
| <p>A custom action in the Commons SCXML implementation has access to: |
| <ul> |
| <li>The current |
| <a href="../apidocs/org/apache/commons/scxml/Context.html">Context</a> |
| (and hence, the values of variables in the current Context). |
| </li> |
| <li>Any other Context within the document, provided the id of the |
| parent <state> is known. |
| </li> |
| <li>The expression |
| <a href="../apidocs/org/apache/commons/scxml/Evaluator.html">Evaluator</a> |
| for this document, and hence the ability to evaluate a given |
| expression against the current or a identifiable Context. |
| </li> |
| <li>The list of other actions in this |
| <a href="../apidocs/org/apache/commons/scxml/model/Executable.html">Executable</a> |
| .</li> |
| <li>The "root" Context, to examine any variable values in the |
| "document environment".</li> |
| <li>The |
| <a href="../apidocs/org/apache/commons/scxml/EventDispatcher.html">EventDispatcher</a>, |
| to send or cancel events.</li> |
| <li>The |
| <a href="../apidocs/org/apache/commons/scxml/ErrorReporter.html">ErrorReporter</a>, |
| to report any errors (that the ErrorReporter knows how to handle).</li> |
| <li>The histories, for any identifiable <history>.</li> |
| <li>The |
| <a href="../apidocs/org/apache/commons/scxml/NotificationRegistry.html">NotificationRegistry</a>, |
| to obtain the list of listeners attached to identifiable |
| "observers".</li> |
| <li>The engine log, to log any information it needs to.</li> |
| </ul> |
| </p> |
| |
| </subsection> |
| |
| </section> |
| |
| <section name="Walkthrough - Adding a 'hello world' custom action"> |
| |
| <p>Lets walk through the development of a simple, custom "hello world" |
| action.</p> |
| |
| <subsection name="Idea"> |
| |
| <p>We need a <hello> action in our (fictitious) namespace |
| "http://my.custom-actions.domain/CUSTOM". The action "tag" will |
| have one attribute "name". The action simply logs a hello to the |
| value of the name attribute when it executes.</p> |
| |
| <p>A simple example is |
| <a href="http://svn.apache.org/repos/asf/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/custom-hello-world-01.xml">here</a> |
| .</p> |
| |
| </subsection> |
| |
| <subsection name="Custom action implementation"> |
| |
| <p>A custom action must extend the Commons SCXML |
| <a href="../apidocs/org/apache/commons/scxml/model/Action.html">Action</a> |
| abstract base class.</p> |
| |
| <p>Here is the Java source for our custom |
| <a href="../xref-test/org/apache/commons/scxml/model/Hello.html">Hello</a> |
| action. The execute() method contains the logging statement.</p> |
| |
| </subsection> |
| |
| <subsection name="Using a custom SCXML digester"> |
| |
| <p>With the custom action(s) implemented, the document may be |
| parsed using a custom SCXML digester that is aware of these actions |
| like so:</p> |
| |
| <pre> |
| // (1) Create a list of custom actions, add as many as are needed |
| List customActions = new ArrayList(); |
| CustomAction ca = |
| new CustomAction("http://my.custom-actions.domain/CUSTOM", |
| "hello", Hello.class); |
| customActions.add(ca); |
| |
| // (2) Parse the SCXML document containing the custom action(s) |
| SCXML scxml = null; |
| try { |
| scxml = SCXMLParser.parse(url, errorHandler, customActions); |
| // Also see other methods in SCXMLParser API |
| // "url" points to SCXML document |
| // "errorHandler" is SAX ErrorHandler |
| } catch (Exception e) { |
| // bad document, take necessary action |
| } |
| </pre> |
| |
| <p>This approach can only be used if the custom |
| rule has no body content (child "tags") or if the custom action |
| implements the |
| <a href="../apidocs/org/apache/commons/scxml/model/ExternalContent.html">ExternalContent</a> |
| interface, in which case, any body content gets read into a list |
| of DOM nodes. For any other requirements, the digester rules |
| can be added by directly by obtaining a Digester instance with the |
| "default" SCXML rules using the <code>newInstance()</code> methods |
| and further directly adding the necessary rules using the |
| <a href="http://commons.apache.org/digester/commons-digester-1.8/docs/api/">digester API</a> |
| .</p> |
| |
| </subsection> |
| |
| <subsection name="Read in the 'custom' SCXML document"> |
| |
| <p>For documents without custom actions, the utility methods of the |
| <a href="../apidocs/org/apache/commons/scxml/io/SCXMLParser.html">SCXMLParser</a> |
| should be used. That section is |
| <a href="core-parser.html">here</a>.</p> |
| |
| </subsection> |
| |
| |
| <subsection name="Launching the engine"> |
| |
| <p>Having obtained the SCXML object beyond step (2) above, |
| proceed as usual, see the section on the |
| <a href="core-engine.html">Commons SCXML engine</a> |
| for details.</p> |
| |
| </subsection> |
| |
| </section> |
| |
| </body> |
| |
| </document> |