Get More from DOORS with DXL Links

Illustrated with a Project Dictionary

by Ian Alexander

www.scenarioplus.org.uk

In an earlier article (Get More from DOORS with DXL Graphics), I introduced some of the features of DOORS and DXL, and illustrated how these powerful tools could be used to create custom graphics outputs from a module in the database. Here I will introduce some of the capabilities for dealing with links between documents.

Introducing Links and Traceability

The central reason for using a requirements management database tool is to assure accurate traceability – between specifications and actual business needs; between design and specifications; between tests and requirements. One test may demonstrate that several requirements have been satisfied; one design element may satisfy numerous requirements at a stroke; and one simple requirement may ultimately demand many design elements and much testing. This many-to-many complexity – along with creeping change to requirements – is what all too often defeats poorly-controlled projects.

DOORS meets the challenge of traceability by providing separate document-like modules, connected by any number of different types of directional links. Most projects use at least two types, such as ‘satisfies’ for basic traceability of design and specifications at all levels, and ‘verifies’ for all demonstrations (whether by test or other means) that the system is indeed implemented correctly. DOORS records each type of trace as the name of a Link Module. One such module may hold numerous sets of links: for instance, you might have one set of ‘satisfies’ links between the Formal Modules for your Design and your Specifications, and another set of the same type between the Formal Modules for your Specifications and your Requirements. To avoid hopeless confusion, you need to make all your links point the same way, forwards or backwards.

DOORS therefore provides three data structures for organizing traceability: Link Modules, Linksets, and Links themselves. There are also some structures for setting up automatic default linking options, for use in operations such as drag-and-drop linking. All of these can be created manually with the DOORS user interface; they are also available in DXL.

A Project Dictionary

To illustrate the benefits of creating a custom link mechanism with DXL, we’ll build a simple but effective Project Dictionary. The idea is that users such as analysts write their project documents as usual, but when they come to a term that needs to be defined, they just mark it up, say with Italics.

The Dictionary script in DXL will then search for text marked up with Italic Rich Text, and will automatically construct a dictionary entry from it.

Well, this requires that a Dictionary exists to hold the entries. The obvious choice is to have a separate Formal Module for the Dictionary; we can use the Object Heading for the terms to be defined, and the Object Text for the definitions. This choice makes the Dictionary easy to read and print, as we can simply use DOORS’ default module display, the ‘Standard view’.

The script will therefore look to see if the Dictionary already exists, and open it for writing if it does. Otherwise it will create a suitable Dictionary.

Then the script will walk through the current module, say a Specification, and pick out all the terms marked up in Italics. It mustn’t just put all of them into the Dictionary, as some of them may be duplicates. The script must look to see if the terms are already defined – or at least, recorded but undefined in the Dictionary – and only create a new entry for new terms.

What should the DXL script do with existing terms? It needs to create a link between the marked-up term in the Specification and the existing definition in the Dictionary. In fact, this is the same thing it must do with new terms, except that there it creates the definition first. The links need a home, in the shape of a Link Module whose name explains the purpose of the links: ‘defines terms in’ is suitable, as it cannot be confused with traceability link modules such as ‘satisfies’.

The final step is up to the user: to write in an agreed definition of each entry in the Dictionary. This involves nothing more than editing the text of the objects created by the DXL script in the Dictionary module.

Creating Links with Regular DXL

The key task for the script, after the basic housekeeping involved in checking for the existence of the dictionary’s formal and link modules, is therefore to identify and create the necessary links between uses of terms and their dictionary entries.

The main program is a for loop that hunts down all the chunks of Italic text:

///////////////////// Analyse Definition Links ////////////////////
string oot, ooh, oboth
string tgtName = ""
Object o, tgt
for o in m do {
   oot = richText o."Object Text" // retrieve rich text
   ooh = richText o."Object Heading"
   oboth = ooh " " oot
   RichText rt
   for rt in oboth do { // now look for (italic) markup
      if rt.italic then {
         tgtName = rt.text
         tgt = findNamedDictObject tgtName
         if null tgt then {
            Object defo = create dictMod noOfNewDefs ++ // count # of Definitions created
            defo."Object Heading" = tgtName
            createLink(linkModName, o, defo)
         } else {
            if !alreadyLinked(linkModName, o, tgt) then {
               createLink (linkModName, o, tgt)
            }
         }
         noOfDefs++ // count # of Links created
      }
   }
}

This calls for a function, findNamedDictObject, which checks whether the term is already in the Dictionary.

/////////////////////////////////////////////
Object findNamedDictObject(string tgtName){
// attempt to find a Dictionary object that has a name that matches the specified target
// the use case may be singular or plural; may be in title case or lower case
Object o
string ooh

for o in dictMod do {
   ooh = o."Object Heading"
   if ooh == tgtName then return o
   // naive approach - exact match
   if matchesName(ooh, tgtName) then return o
   // 'intelligent' approach - fuzzy match
}
return null
} // findNamedDictObject

The most interesting part of this is thinking of how a term ought to be matched against an existing entry. The naïve approach is just to demand strict equality, but what if the term is in lower-case and the entry in Title Case? Or if there is an ‘s’ on the end? DXL permits sophisticated pattern-matching using Regular Expressions, but that is the subject for another article.

When a match is found (or a new entry has been created), the remaining job is to link it to the marked-up object. The actual code to create the link is appealingly simple:
void createLink(string linkModName, Object src, Object tgt) {
src -> linkModName -> tgt
}

Finally, there is no point recreating links that have already been put in place properly by an earlier run of the DXL script. The script can search for an existing link by scanning through all the links from an object, and seeing whether the intended target is in fact the target of an existing link. Here is a Boolean function that returns true if it finds that our object and its target are alreadyLinked:

bool alreadyLinked(string linkModName, Object o, Object tgt) {
Link existingLink
for existingLink in o -> linkModName do {
   Object existingTgt = target existingLink
   if existingTgt == tgt then {return true; break}
}
return false
}

Reporting on Links with Layout DXL

Your project team can simply click on the triangular link indicator to go and read any dictionary definitions they are interested in, but this forces them to click and navigate the pop-up menus to see what there is. The alternative is to create a Layout DXL Column which instantly shows them all the dictionary entries that explain marked-up terms in the specifications module itself. This column can be saved in a view, e.g. ‘Defined Terms’, that they can load whenever they want.

The good news here is that almost all the Layout DXL you need to display linked text is in the DXL library. We want to make just two small changes to the library script ‘Show all targets of outgoing links’:

  1. The script should only look for "defines terms in" links
  2. The script should display the whole Object Heading and Object Text, and nothing else.

These changes are highlighted in the script, which resides ‘inside’ the Column that displays it – the script cannot be used as stand-alone DXL.

// column_of_definitions.layout.inc -- layout dxl script for dictionary builder

#include <layout/show.inc>
Link l
setCacheState_ on
for l in obj->"defines terms in" do {
string mn = fullName(target l)
if (!attemptDisplay mn) continue
Object o = target l
Module m
if (null o) {
m = read(mn, false)
o = target l
}
string ooh = o."Object Heading"
string oot = o."Object Text"
display ooh ": " oot

}
setCacheState_ off

You can create a view like this by hand, or it can be set up by the DXL script – to include everything from the Layout DXL code in the ‘Definitions of terms in project dictionary’ column to adding the view itself.

Notice that the code uses a #include command to bring in the Layout DXL, which you need to save in a file, and put in an accessible place in the DXL library. You should test the Layout DXL script before including it in a view like this.

/////////// Set up Dictionary and Defined Terms Views /////////
current = dictMod
Sort dictOrder = ascending "Object Heading"
refresh dictMod
save view "Dictionary"
current = m
Column c
int n = 0
for c in m do n++
for i in 1:n do delete column 0 // start with a clean slate
Column idCol = insert(column 0)
title (idCol, "ID")
attribute(idCol, "Object Identifier")
width (idCol, 60)
Column mainCol = insert(column 1)
title (mainCol, "Text containing italic marked-up terms to be defined")
main mainCol)
width mainCol, 300)
graphics mainCol
info mainCol
Column defCol = insert(column 2)
title (defCol, "Definitions of terms in project dictionary")
width (defCol, 400)
dxl (defCol, "#include <addins/extensions/column_of_definitions.layout.inc>")
refresh m
save view "Defined Terms"
 

Finishing Touches – A Custom Menu

The illustration above also shows a custom menu, ‘Extensions’, on the DOORS menu-bar, including the ‘Build Dictionary from Marked-up Terms’ command. That command simply activates the DXL script; the custom menu is created without coding, by putting a subdirectory (named ‘Extensions’) inside the ‘DOORSHOME/lib/dxl/addins’ directory.

There are three rules for creating a custom menu.

  1. There must be an index file with the same name as the custom directory, e.g. ‘Extensions.idx’, which must be structured like ‘User.idx’ in the User directory. The index file allows you to define a friendly name to be displayed for the command, like ‘Build Dictionary’, rather than the filename which is best kept short and in lower-case.
  2. There must be a plain text help file with the same name as the custom directory, e.g. ‘Extensions.hlp’ – note that this is not a Microsoft Help file but ordinary text. You ought to write a simple explanation in this file of what your custom menu is meant to do.
  3. There must be a single-line // comment at the top of each dxl script, followed by a multi-line /*…..*/ comment. You ought to use these to say in one line what the script is meant to do, and then describe in a little more detail anything the user needs to know about it. It’s also good to record your name, the date, and the version of DOORS to make maintenance easier.

The menu appears automatically – if you have done everything right! – next time you open a Formal Module.

Summary

DXL provides simple and efficient tools for handling DOORS links. These are closely integrated with all the other features of DXL, such as the object manipulation, rich text processing, and indexing used in this example. The effect is to automate what is otherwise a tedious chore, leaving project staff to get on with what they do best, which is to work on the system under development.

That's all you need to do to manage and display specialized links in your DOORS database. Get customizing!

© Ian Alexander, May 2001

Other Articles