User Tools

Site Tools


fsm:tools

Tools usable with the OSInet FSM

Generating FSM from UML State machine diagrams

Since the FSM (>= 1.3) now uses external schema files, it seems only logical to generate these from a visual editor instead of hand-typing them. And with OOo being the de facto standard for office work, OOo Draw seems a logical choice.

In addition, while I'd gladly have used Dia or Inkscape as a drawing tools, both are significantly less easy to use for this type of diagramming (IMHO), so the first UML to FSM converter rests on OOo Draw.

Now, how can one go about it ? Simply enough, with OpenDocument being an open standard, its layout is rather obvious.

However, in the long run, Dia has dedicated UML formatting, and hence seems a more logical choice, although it is far less easy to use. So the maintained converter, at least for now, uses Dia files.

OOo Draw to FSM

A FSM subset for OOo Draw

The data in OpenDocument drawings is held in the office:document-content/office:body/office:drawing/draw:page element of the content.xml file in the zipped archive making up an OpenDocument document.

A FSM diagram source only needs two element types (rect: rectangles, and connector: transitions), so we can ignore all other elements.

  • The rect elements are used for the states. We only use their ID and the content of their 'text:p' child as the state name
  • The connector element has several attributes and a child element, but only a few are useful for this application
    • draw:start-shape defines the ID of the transition entry state
    • draw:end-shape defines the ID of the transition exit state
    • the child text:p element defines UML description of the transition, the content of which we can parse as an UML description
      • name
      • event guard (ignored in version 1.3)
      • output conditions
      • action

Sample data

This following excerpt represents the useful part of a two-state transition diagram:

   [..snip..]
    <draw:page draw:name="page1" draw:style-name="dp1" draw:master-page-name="Standard">
      <office:forms form:automatic-focus="false" form:apply-design-mode="false"/>
      <draw:rect draw:style-name="gr1" draw:text-style-name="P1" draw:id="id1" 
        draw:layer="layout" 
	svg:width="4.5cm" svg:height="3.5cm" svg:x="2.5cm" svg:y="3.5cm">
        <text:p/>
	</draw:rect>
      <draw:connector draw:style-name="gr2" draw:text-style-name="P1" 
        draw:layer="layout" draw:type="curve" 
	svg:x1="4.75cm" svg:y1="7cm" svg:x2="11.75cm" svg:y2="15.5cm" 
	draw:start-shape="id1" draw:start-glue-point="2" 
	draw:end-shape="id2" draw:end-glue-point="0">
        <text:p text:style-name="P2">Square 1 to 2</text:p>
	</draw:connector>
      <draw:rect draw:style-name="gr1" draw:text-style-name="P1" draw:id="id2" 
        draw:layer="layout" 
	svg:width="6.5cm" svg:height="4.5cm" svg:x="8.5cm" svg:y="15.5cm">
        <text:p/>
	</draw:rect>
      </draw:page>
  [..snip..]

Parsing the graph

Supposing for now that the OOo document has already been unzipped to directory draw2, here is a possible piece of code to parse the FSM:

error_reporting(E_ALL|E_STRICT);
 
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->load('draw2/content.xml');
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('office', "urn:oasis:names:tc:opendocument:xmlns:office:1.0");
$xpath->registerNamespace('draw',   "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0");
$xpath->registerNamespace('text',   "urn:oasis:names:tc:opendocument:xmlns:text:1.0");
 
$qtext = 'text:p';
$qnodes = '('
  . '//office:document-content/office:body/office:drawing/draw:page/draw:rect'
  . '|'
  . '//office:document-content/office:body/office:drawing/draw:page/draw:connector'
  . ')';
$result = $xpath->query($qnodes, $doc);
foreach ($result as $node)
  {
  $name = $node->tagName;
  switch ($name)
    {
    case 'draw:rect':
      $id = $node->getAttribute('id');
      $restext = $xpath->query($qtext, $node);
      $textnode = $restext->item(0);
      $state = $textnode->nodeValue;
      $states[$id] = $state;
      break;
    case 'draw:connector':
      $start = $node->getAttribute('start-shape');
      $end   = $node->getAttribute('end-shape');
      $restext = $xpath->query($qtext, $node);
      $textnode = $restext->item(0);
      $event = $textnode->nodeValue;
      $events[$start][$end] = $event;
      break;
    default:
      // nothing
    }
  }

From there on, it's a simple matter of merging the two trees and generating the resulting FSM XML file.

Dia UML to FSM

Like OOo, Dia saves its content in an easy to parse zipped XML format.

Since Dia includes dedicated UML widgets, these can be used to semantically extract them instead of relying on format limitations as was the case in the OOo converter test.

The elements recognized are:

  • “UML - State Term”: used for initial and final states
  • “UML - State”: used for other states
  • “UML - Transition”: used for transitions. Properties include:
    • Trigger (event)
    • Guard (event outcome)
    • Action (post-state-switch behaviour)

Other UML elements are available but not processed yet. The “UML - Fork” division/reunion bar could be the next addition, but state nesting is not being considered.

fsm/tools.txt · Last modified: 2020/11/23 17:23 by 127.0.0.1