Apache Commons logo Commons SCXML

What is a 'custom action'?

Actions are SCXML elements that "do" something. Actions can be used where "executable content" is permissible, for example, within <onentry>, <onexit> and <transition> elements.

The SCXML specification (currently a Working Draft) defines a set of "standard actions". These include <var>, <assign>, <log>, <send>, <cancel>, <if>, <elseif> and <else>.

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.

Custom actions with Commons SCXML

Commons SCXML makes authoring custom actions fairly straightforward.

What can be done via a custom action

A custom action in the Commons SCXML implementation has access to:

  • The current Context (and hence, the values of variables in the current Context).
  • Any other Context within the document, provided the id of the parent <state> is known.
  • The expression Evaluator for this document, and hence the ability to evaluate a given expression against the current or a identifiable Context.
  • The list of other actions in this Executable .
  • The "root" Context, to examine any variable values in the "document environment".
  • The EventDispatcher, to send or cancel events.
  • The ErrorReporter, to report any errors (that the ErrorReporter knows how to handle).
  • The histories, for any identifiable <history>.
  • The NotificationRegistry, to obtain the list of listeners attached to identifiable "observers".
  • The engine log, to log any information it needs to.

Walkthrough - Adding a 'hello world' custom action

Lets walk through the development of a simple, custom "hello world" action.

Idea

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.

A simple example is here .

Custom action implementation

A custom action must extend the Commons SCXML Action abstract base class.

Here is the Java source for our custom Hello action. The execute() method contains the logging statement.

Using a custom SCXML reader

With the custom action(s) implemented, the document may be parsed using a SCXMLReader that is made aware of these actions through a custom Configuration like so:

      // (1) Create a list of custom actions, add as many as are needed
      List<CustomAction> customActions = new ArrayList<CustomAction>();
      CustomAction ca =
            new CustomAction("http://my.custom-actions.domain/CUSTOM",
                             "hello", Hello.class);
      customActions.add(ca);

      // (2) Read the SCXML document containing the custom action(s)
      SCXML scxml = null;
      try {
          scxml = SCXMLReader.read(url, new SCXMLReader.Configuration(null, null, customActions));
          // Also see other methods in SCXMLReader API
      } catch (Exception e) {
          // bad document, take necessary action
      }
    

This approach can only be used if the custom rule has no body content (child "tags") or if the custom action implements the ExternalContent interface, in which case, any body content gets read into a list of DOM nodes. .

Read in the 'custom' SCXML document

For documents with or without custom actions, several utility methods of the SCXMLReader can be used. More information is here.

Launching the engine

Having obtained the SCXML object beyond step (2) above, proceed as usual, see the section on the Commons SCXML engine for details.