XQuery/Sequence Diagrams
Background
[edit | edit source]Sequence Diagrams are tedious to draw, even with a diagramming tool. They are even worse to edit when the sequence changes. An alternative is to define an XML vocabulary to define the message sequencing and to use XQuery to render this description as XHTML. This textual approach also allows explanations to be revealed at each step and alternative renderings of the XML definition of the Sequence to be generated, such as a printed version.
This demonstrator uses a simplified meta-model, with only messages between actors and actions undertaken by actors.
(article under re-design - CW)
Models
[edit | edit source]3-tier architecture
[edit | edit source]Here is a sample description of interaction in a 3-tier architecture: (badly needs re-writing)
<SequenceDiagram id="3tier"> <name>3-tier architecture</name> <description>An overview of the 3-tier Architecture</description> <cast> <actor> <name>user</name> <label>The User</label> <color>pink</color> <location>client</location> <description>The user of the site</description> </actor> <actor> <name>browser</name> <label>Presentation Layer</label> <color>lightgreen</color> <location>client</location> <description>A browser such as Firefox, Opera or Internet Explorer</description> </actor> <actor> <name>server</name> <label>Application Layer</label> <color>lightblue</color> <location>server</location> <description>Scripts in languages such as PHP or Java invoked via a web server</description> </actor> <actor> <name>database</name> <label>Persistance Layer</label> <color>grey</color> <location>server</location> <description>A database server such as Oracle or MySQL</description> </actor> </cast> <communication> <connection> <actor>user</actor> <actor>browser</actor> <method/> <prep>on</prep> </connection> <connection> <actor>browser</actor> <actor>server</actor> <method>HTTP</method> <prep>to</prep> </connection> <connection> <actor>server</actor> <actor>database</actor> <method>SQL</method> <prep>to</prep> </connection> </communication> <trace> <message> <from>user</from> <to>browser</to> <action>click</action> <object>link</object> </message> <message> <from>browser</from> <to>server</to> <action>request</action> <object>URL</object> <url>http://www.cems.uwe.ac.uk/~cjwallac/apps/poll2/tally.php?pollid=2</url> </message> <do> <at>server</at> <action>decode input</action> <object/> </do> <do> <at>server</at> <action>create SQL request</action> <object/> </do> <message> <from>server</from> <to>database</to> <action>request</action> <object>SQL statement</object> </message> <message> <from>database</from> <to>server</to> <action>respond</action> <object>tables</object> </message> <do> <at>server</at> <action>create page with data in table</action> <object/> </do> <message> <from>server</from> <to>browser</to> <action>respond</action> <object>HTML page</object> </message> <message> <from>user</from> <to>browser</to> <action>read</action> <object>page</object> </message> </trace> </SequenceDiagram>
Rendering the diagram
[edit | edit source]The script 'displayDiagram' renders this model as an XHTML table:
declare option exist:serialize "method=xhtml media-type=text/html indent=yes"; declare variable $homesym :=' || '; declare variable $leftsym := ' >> '; declare variable $rightsym := ' << '; declare function local:makeText($event){ concat($event/action,' ',string-join($event/object,' + ')) }; let $id:= request:get-parameter('id','') let $sd :=//SequenceDiagram[@id=$id] let $trace := $sd/trace let $actors := $sd/cast/actor let $nactors := count($sd/cast/actor) let $width := 100 div $nactors return <html> <head><title>Sequence Diagram {string($sd/@id)}</title> </head> <body> <h1>{string($sd/name)} </h1> <div class="description"> {$sd/description/node() } </div> <table border='1'> <tr> {for $a in $actors return <th width='{$width}%' bgcolor='{$a/color}'>{string($a/label)}</th> } </tr> { if ($actors/description) then <tr> {for $a in $actors return <th width='{$width}%' bgcolor='{$a/color}'>{string($a/description)} </th> } </tr> else () } {for $event in $trace/* return <tr> {if (name($event)='do') then let $p := index-of($actors/name,$event/at ) let $text:= local:makeText($event) return ( for $i in (1 to $p - 1) return <td/>, <td align='center' bgcolor='{$actors[name=$event/at]/color}'> { if ($event/url) then <a href='{$event/url}' target='demo'>{$text}</a> else $text } </td>, for $i in ($p + 1to $nactors) return <td/> ) else if (name($event)='message') then let $pfrom := index-of($actors/name,$event/from ) let $pto := index-of($actors/name,$event/to) let $pfirst := min (($pfrom,$pto)) let $plast := max(($pfrom,$pto)) let $ltor := $pfrom = $pfirst let $text:= local:makeText($event) let $connection := $sd//connection[actor = $event/from and actor= $event/to] let $text := if ($ltor) then concat($connection/method,$leftsym,$text,$leftsym) else concat($rightsym,$text,$rightsym, $connection/method) return ( for $i in (1 to $pfirst - 1) return <td/>, <td align='center' colspan='{$plast - $pfirst + 1 }' bgcolor ='{$actors[name=$event/from]/color}' > {$text} { if ($event/url) then <a href='{$event/url}' target='demo'>Link </a> else () } </td>, for $i in ($plast + 1 to $nactors) return <td/> ) else () } </tr> } </table> </body> </html>
Further example Diagrams
[edit | edit source]- A GoogleEarth application
Animating the Diagram
[edit | edit source]Rather than display the complete interaction, the diagram can be simply animated by displaying only the first n steps, together with explanatory text for the last step. The addition of some controls allows the user to step forward and backward in the sequence.
3 Tier GoogleEarth A function to compute the next step:
declare function local:next-step($step,$action, $max) { if ($action = "start") then 0 else if ($action = "back") then max (($step -1,0)) else if ($action = "forward") then min(($max,$step+1)) else if ($action="end") then $max else $step };
and call the function
let $step := local:next-step( number(request:request-parameter("step",0)), request:request-parameter("action", "start"), count($trace/*))
A form to provide the controls and maintain the interaction state:
<h2> <form> <input type="hidden" name="id" value="{$id}"/> <input type="hidden" name="step" value="{$step}"/> <input type="submit" name="action" value="start"/> <input type="submit" name="action" value="back"/> <input type="submit" name="action" value="forward"/> <input type="submit" name="action" value="end"/> </form> </h2>
Limit the events displayed to the specified number of steps:
for $event in $trace/*[position()<=$step]
and display the explanation of the last step:
<div class="description"> {if ($step=0) then $sd/description/node() else $trace/*[position()=$step]/description/node() } </div>
Print the diagram
[edit | edit source]One of the advantages of having the whole diagram in XML is that the diagram can be displayed differently in print, so that each step can be shown with its description.