The process definition file format is defined by an XSD, which is available to view in the project SVN .
We'll explore the Sarasvati file format, starting with the root element and working from there, with examples interspersed.
This is the root element. It should indicate the XML namespace, that being:
http://sarasvati.googlecode.com/ProcessDefinition
Table 4.1. process-definition
attributes
Attribute Name | Usage | Is Required? | Default Value |
---|---|---|---|
name | The unique name for this process definition. | Yes | N/A |
Table 4.2. process-definition
nested elements
Element | Description |
---|---|
node |
Every process-definition must have a least one node defined.
|
external | An external declares a process definition to be included. More than one external process definition may be included and the same process definition may be included more than once with a different name for each include. |
Nodes in a process definition are defined by the node
element. Every node must have a name unique to that file.
Table 4.3. node
attributes
Attribute Name | Usage | Is Required? | Default Value |
---|---|---|---|
name | The name of this node. The name must be unique within this process definition. | Yes | N/A |
type | The node type. Determines the node behavior. | No | node |
isStart | Specifies whether a node will be presented with a token when the process is started. | No | false |
joinType | Determines the join strategy the node should use when a token arrives. Some nodes may accept incoming tokens as soon as they arrives, others may act as gates, waiting until a certain number of nodes arrive or token exist on specific incoming arcs before executing. See below for the allowed join types. | No | or |
joinParam | Some join strategies, such as the token set join, may join based on this paramter. Alternately, this can be used by the custom join type as the developer desires. | No | N/A |
Table 4.4. node
nested elements
Element | Description |
---|---|
guard | Each node may have a single, optional guard element. The guard is generally defined in the Rubric rules language and will be evaluated when the node's join strategy determines that the node is to be executed. The guard will determine if the node should be executed, skipped or if the newly created node token should be discarded. |
arc | Nodes may have zero to many arcs, pointing to other nodes in the same process definition. Arcs link together nodes and provide the paths along with the flow of execution proceeds. |
custom | Each node has a custom section which may contain any user defined elements. How data from these custom elements is loaded is explained in the section on custom node attributes below. |
Every node defines a join strategy, which is invoked when tokens arrive at the node and determines when the node is ready to be executed.
Table 4.5. node
join types
Type | Behavior |
---|---|
or |
An or join will be satisfied any time an arc token arrives at the node.
|
and |
An and join will be satisfied when an arc token arrives and there are
arc tokens waiting at all other incoming arcs to the node. In most cases the
labelAnd is safer and more flexible.
|
labelAnd |
A labelAnd join will be satisfied when an arc token arrives
and there are arc tokens waiting at all other incoming arcs to the node which
share the same name/label as the arc that the arc token is arriving on.
|
tokenSetAnd |
A tokenSetAnd join will be satisfied when all active arc tokens
in the set are on incoming arcs to the same node and there are no active node tokens
in the token set. An exception will be raised if a non-token set token arrives.
|
tokenSetOr |
A tokenSetOr join will be satisfied when all active arc tokens
in the set are on incoming arcs to the same node and there are no active node tokens
in the token set. The or strategy will be used as a fallback if
a non-token set token arrives.
|
custom | Users may use custom join strategies. See the API reference for more detail. |
node
- Nodes of this type will complete out on the default arc
when they are executed. The node type can be useful if a
synchronization point is needed. It can also be used as a
choice mechanism, by specifying a guard which skips to
selected arcs.
wait
- Nodes of this type will enter a wait state when
executed. They will continue when completed by external
logic. This can be useful when you need to wait on an
external event, and no other logic is required.
script
- Requires a script
element which will contain a script
to execute when the node is executed.
A node may contain a GuardLang statement, which will be executed as the node's guard. The guard element has no attributes and may contain no nested elements.
With just process-definition
and node
a simple process definition
can be built.
The simplest process definition would be a single node. Graphically, it would look like:
The corresponding XML process definition would look like:
<?xml version="1.0"?> <process-definition name="simplest" xmlns="http://sarasvati.googlecode.com/ProcessDefinition"> <node name="node-one" isStart="true"/> </process-definition>
While there can be many nodes declared in a process definition, we have as yet, not defined a way of linking them together.
An arc
element declares an arc from the enclosing node to the node
with the name specified in the to
attribute. An arc is allowed no nested elements.
Table 4.6. arc
attributes
Attribute Name | Usage | Is Required? | Default Value |
---|---|---|---|
to | Specifies the name of the node this arc goes to. | Yes | N/A |
name | Specifies the arc name. This name need not be unique. | No | null |
external |
If this arc is linking to an external (see below for more information on externals),
the name of the external being linked to. If an external attribute
is specified then the to attribute will refer to a node in the
external, not a locally defined node.
| No | null |
The following example contains three nodes.
<?xml version="1.0"?> <process-definition name="example2" xmlns="http://sarasvati.googlecode.com/ProcessDefinition"> <node name="node-one" isStart="true"> <arc to="node-two"/> <arc to="node-three"/> </node> <node name="node-two"/> <node name="node-three"/> </process-definition>
To indicate an arc, an
arc
element is added to the start node. The
to
attribute indicates the name of the target node. A node with
that name must exist in the same process definition file.
Here is an example with two start nodes. They both have arcs
to
node-three
, which uses the labelAnd
join strategy. It will only execute once both
node-one
and
node-two
have completed.
<?xml version="1.0"?> <process-definition name="example3" xmlns="http://sarasvati.googlecode.com/ProcessDefinition"> <node name="node-one" isStart="true"> <arc to="node-three"/> </node> <node name="node-two" isStart="true"> <arc to="node-three"/> </node> <node name="node-three" joinType="labelAnd"/> </process-definition>
Now that we've seen how to create links between nodes in the same process definition, let us examine how to include external process definitions and create links to them.
An exernal process definition must have a declaration for each time it is to be included.
Table 4.7. external
attributes
Attribute Name | Usage | Is Required? | Default Value |
---|---|---|---|
name | The name by which this external process definition will be referred to. The name must be unique within this process definition. | Yes | N/A |
processDefinition | The name of the process definition being included. The same process definition may be included more than once. | Yes | N/A |
Table 4.8. external
nested elements
Element | Description |
---|---|
arc | Externals may have zero to many arcs. The arcs originate in the extenal process definition. They may end in nodes in the same process definition, in other externals or even in the same external. |
custom | Each external has a custom section which may contain any user defined elements. How data from these custom elements is made loaded is explained in the section on custom external attributes below. |
An arc
element in an external
declares an arc
from a node in the enclosing external to the node with the name specified in
the to
attribute. An arc is allowed no nested elements.
Table 4.9. arc
attributes
Attribute Name | Usage | Is Required? | Default Value |
---|---|---|---|
from | Specifies the name of the node in the external that this arc starts from. | Yes | N/A |
to | Specifies the name of the node this arc goes to. | Yes | N/A |
name | Specifies the arc name. This name need not be unique. | No | null |
external |
If this arc is linking to another external, this specifies the name of the external
being linked to. If an external attribute is specified then the
to attribute will refer to a node in the external, not a locally
defined node.
| No | null |
To examine external arcs, we'll need at least two process definitions.
This example is from the EngineConcepts section.
<?xml version="1.0"?> <process-definition name="ext" xmlns="http://sarasvati.googlecode.com/ProcessDefinition"> <node name="A" joinType="labelAnd"> <arc to="B"/> </node> <node name="B" joinType="labelAnd"/> </process-definition>
It looks like:
The graph which contains external arcs going to 'ext', is below.
<?xml version="1.0"?> <process-definition name="example4" xmlns="http://sarasvati.googlecode.com/ProcessDefinition"> <node name="P" isStart="true"> <arc external="1" to="A"/> </node> <node name="Q" isStart="true"> <arc external="2" to="A"/> </node> <node name="R" isStart="true"> <arc external="2" to="B"/> </node> <node name="X"> <arc to="Z"/> </node> <node name="Y"> <arc to="Z"/> </node> <node name="Z" joinType="labelAnd"/> <external name="1" processDefinition="ext"> <arc from="A" to="X"/> </external> <external name="2" processDefinition="ext"> <arc from="B" to="Y"/> </external> </process-definition>
It looks like:
When the process definition is loaded into memory, it will look like:
The process definition file format also supports custom elements and attributes, but before we discuss that, the API needs to be introduced.