The Coad Letter: Modeling and Design, Issue 111, Using Stereotypes in Document Generation, by Stephen Palmer
Borland's Together ControlCenter includes a very powerful reporting engine.
It is capable of generating plain text, RTF or HTML documents from models held
in Together. Commonly referred to as GenDoc after the Java package name of its
Together module, the engine works from user definable templates. In this article
we examine three handy strategies for using GenDoc and introduce some of the
basic GenDoc template designer concepts as we do so. The article assumes a basic
familiarity with UML and Together ControlCenter and was written with reference
to Together 6.0.1 and 6.1.
GenDoc Strategy #2003-1: Create a Diagram for a Document
When the diagrams that form the desired contents of a document do not fall
conveniently under the same package, create a diagram to represent the document
and add the desired contents as shortcuts.
The GenDoc module is invoked by selecting Project|Documentation|Generate
Using Template... from Together's main menu bar and completing the resulting
pop up dialog box.
Figure 1: Together 6's Generate Documentation Using Template dialog box
The scope options determine the parts of the project currently open in Together
that the GenDoc engine will consider for inclusion as it generates a document.
These are reasonably self-explanatory. However, what if the diagrams we want
in our document are not conveniently grouped within a package and its sub-packages?
For example, the desired contents of a component design document might include:
- one or more UML deployment diagrams showing the context of the component,
- a class diagram showing supported interfaces,
- a class diagram showing the domain classes of which the component comprises
- sequence diagrams showing typical usage of the component
- sequence diagrams showing the object interactions within the component
- one or more ERD diagrams showing a relational database schema used by the
component to persist data.
Imagine that these documents are scattered across a package hierarchy according
to their type rather than grouped by component. In this case it is not immediately
obvious how to set the scope to achieve what we need. The answer is to select
the current diagram option but for this to work we need to do a little work
Note: Debates about exactly what should and what should not be included in
a design document are thankfully completely besides the point for this article.
The above list serves as a good enough example for our purposes. Likewise
debates on the optimal UML or Java package hierarchy for component based development
are outside the scope of this article.
Diagrams and Shortcuts
Together diagrams can contain links or, in Together terminology, shortcuts
to other diagrams. Therefore, we can create a new diagram and add to it shortcuts to all the other diagrams we want as part of the document. Our new diagram
is acting as a container for links to the contents of the documents. This strategy
has an additional benefit. We can use the inspector pane properties of the containing
diagram to hold information like the title and introductory description for
Figure 2: A component diagram being used to collect together the contents
for a document. Note the description property of the diagram is being used to
store the introduction to the document.
Now we can use the Current Diagram scope in the Generate Documentation Using
Template dialog box. However, there is still a slight hitch. We cannot use
the report templates supplied with Together 6 because they are not set to traverse
shortcuts. In many circumstances this is the correct setting because it would
often lead to duplicated information in a generated document. However, our strategy
is one of those times when we do want the GenDoc engine to traverse shortcuts.
This gives us a good excuse to examine GenDoc templates in a little more detail.
The templates used by the GenDoc engine are text files produced by Together
ControlCenter's Documentation Template Designer. You can fire up the
designer by pressing the Design button in the Generate Documentation
Using Template dialog box (see figure 1) or by selecting Project|Documentation|Design
Templates... from Together's main menu bar.
Figure 3: The Together 6 Documentation Template Designer
Each template consists of a number of sections of various types including:
- report and page headers and footers,
- static sections,
- calls to other templates,
- calls to stock sections,
- folder sections,
- element and property iterators
Header, footer and static sections are containers for information and controls
that retrieve and format elements from a Together project. Folder and iterator
sections are containers for other sections. Call sections include the contents
of other templates or reusable chunks from within the same template known as
Defining a new report template consists of adding the desired sections, defining
the properties of those sections and, as appropriate, adding various information
and controls to define the actual contents of each section. A new section is
added by right clicking on an existing section in the left-hand part of the
Template Designer and selecting either Insert Sibling Section or Insert
Nested Section as appropriate.
The heart of any GenDoc template is its iterator sections. These powerful little
beasties contain sections that are repeated for each model element within the
current scope. For example, we can define an iterator to process all the class
diagrams in the report scope. Because we can nest iterator sections, we can
then define an iterator to process all the classes in each of those diagrams,
and then all the operations, and then all the properties of those operations,
and so on. The MetaType and Scope Option properties of an iterator determine
what exactly is included by the iterator. The MetaType determines the types
of model element included and the scope options apply other conditions and filters
to those elements.
Figure 4: Scope Options of an Element Iterator
By default all the Search Options in the MetaType properties of an iterator
are set to no. For our strategy we need to set the Include Shortcuts
setting to yes. This will ensure that the shortcuts in our containing
diagram will be traversed and the contents of the contained diagrams included
in the generated document.
GenDoc Strategy #2003-2: Use Diagram Stereotypes to
When you need to distinguish between diagrams of the same sort so that they
appear in different parts of a generated document, assign different stereotypes
to the diagrams. Then add filter expressions to iterator sections of the GenDoc
template so that only the diagrams with the relevant stereotype are processed
by each iterator.
Frequently, the same sort of UML diagram is used to communicate different aspects
of a model. In our example of a component design document some class diagrams
are used to specify the interfaces that a component provides. Other class diagrams
describe the domain model classes that comprise the component. Both are UML
class diagrams but they are being used for two different purposes.
Probably the most widely known extension mechanism of UML is the use of stereotypes.
UML stereotypes are used to further classify an element in a UML model.
Note: By default, stereotypes are shown as a name surrounded by guillemot
characters. Guillemot characters are the quote marks used in some European
languages. Because guillemots look like a pair of angle brackets, this is
an accepted alternative representation for those of us who do not have easy
access to these European characters on our keyboards.
Stereotypes can be applied to almost anything in the UML, including classes,
attributes, operations, and associations in class diagrams. Together also allows
a stereotype to be set for a UML diagram. This means we can further classify
the type of a UML diagram in Together by providing a value for its stereotype
property in the inspector pane. For example, we can give the class diagrams
depicting our component's interfaces a stereotype of <<component interface>>.
In the same way, we can give the class diagrams showing our component's business
objects a stereotype of <<problem domain>>.
Figure 5: Using stereotypes to indicate different purpose of the same type
of UML diagram
Iterator Filter Expressions
To make use of the diagram stereotypes we need to add a filter expression to
the relevant element iterator sections of our GenDoc template. To do this right
click on the element iterator and select properties. In the tabbed dialog that
pops up select the scope options tab. In the filter expression box at the bottom
of this tab (see figure 4) type hasPropertyValue("stereotype","problem
domain") to only include diagrams to which we have given the <<problem
domain>> stereotype. Similarly type hasPropertyValue("stereotype","component
interface ") to only include diagrams to which we have given the <<component
Note: The hasPropertyValue() function returns true only if the diagram
or model element under consideration has a property with the specified name
(first parameter) and that property has the specified value (second parameter).
We could do something similar with diagram names but the added benefit of using
stereotypes is we can include multiple diagrams of each stereotype. If we filtered
on diagram name we could only include one of each type and the use of an iterator
section would be redundant. Using the stereotype property is much more flexible.
Although Together has a dropdown list of stereotypes, it also allows the entry
of any reasonable character string as a stereotype name so we can apply this
strategy to our hearts' content. For example, we might want to have one or more
overview class diagrams before a set of more detailed class diagrams. We can
achieve this easily with diagram stereotypes. First add an element iterator
with metatype class diagram that only included diagrams with a stereotype of
<<domain overview>>. Then add a subsequent element iterator with
metatype class diagram that processes diagrams with a stereotype of <<problem
The Together User Guide lists a number of different functions that can be used
in iterator filter expressions. These functions can be combined with the usual
Java/C++ style operators but must eventually evaluate to either true or false.
If the result is true the element under consideration is processed by the iterator.
If the result is false the element is ignored.
GenDoc Strategy #2003-3: Use Alias Properties for More
Create GenDoc templates that use the value of a diagram or model element's
alias property if it has been set or the value of the name property otherwise.
Alias properties enable Together packages, diagrams, classes and interfaces
to have names that conform to program language or file system naming rules while
displaying something a little more readable in diagrams. Alias properties can
also be used to good effect in generated documents. However sometimes entering
a value for an alias property is overkill or it is omitted for expedience. Also
some model elements in Together do not, by default, have an alias property (for
consistency it would perhaps be nice if all diagrams and model elements in Together
did have alias properties but that is a debate for another time and place).
Static sections have a property called an enabling condition. If the expression
entered as the value of this property evaluates to false, the contents of the
static section are not included in the generated document. This enables optional
sections of documents to be set up or a template to have competing sections
with mutually exclusive enabling conditions. Alias and name properties in document
headings are one good example of this. If the alias property is populated we
want this to be used as a heading in our generated document but if it is not
we want to use the value of the name property instead. Therefore we declare
two static sections one containing a data control for the alias property and
one containing a data control for the name property.
In the enabling condition property of the Name static section we enter !hasProperty("alias").
In the enabling condition property of the Alias static section we enter
Note: The hasProperty() function returns true only if the diagram
or model element under consideration has a property with that name and that
property has been given a value.
Figure 6: A template snippet with two competing static sections, one for
the alias property and one for the name property
Figure 7: The enabling condition for the static section with the name property.
We can achieve the same thing more concisely using a formula control but it
requires us to know a little more about the scripting language used by GenDoc
(and Together's *.config files). Instead of two static sections we use one static
section and give it a formula control with the expression:
if (hasProperty("alias"), getProperty("alias"), getProperty("$name"))
Here, if the first term in the if statement evaluates to true then the second
term is evaluated and used as the result of the expression. If the first term
evaluates to false, the third term is used instead. You will note that the name
property has a $ character in front of it but neither alias nor stereotype need
one. The exact reason for this difference involves the mysterious MetaModel.mm
file found in the GenDoc template directory and is a topic for another time.
GenDoc is a powerful and under-used feature of Together. In circumstances where
standard documents are needed to meet an organization's process or policy, it
can prove to be a huge time saver for a development project team. I hope this
article has provided a glimpse of how, with some investment in learning to use
it, GenDoc can be invaluable in reducing the tedious work of cutting and pasting
diagrams and content out of Together and into web or word processor documents.
With special thanks to Richard Pitt at Borland UK for his suggestions and corrections.
Also thanks to Elena Alekseeva in the Together Labs, St. Petersburg, Russia,
and The Great Don Kranz in the USA for their patience and help as my brain has
slowly battled to come to grips with various aspects of GenDoc templates over
the last few years.