Drawing UML Diagrams with UMLGraph
Diomidis Spinellis
Department of Management Science and Technology
Athens University of Economics and Business
Athens, Greece
dds@aueb.gr
Introduction
UMLGraph allows the declarative specification and drawing of
UML class and sequence diagrams.
The specification is done in text diagrams, that are then
transformed into the appropriate graphical representations.
There is no rule specifying that models should appear in a graphical
form. A model is a simplification of reality, so a model for a software
artifact could really be an outline of that artifact; think of a class
definition without code in the method bodies. However, we usually
prefer to examine many of our models in a graphical representation: UML
employs ten different diagrams for visualizing different perspectives
of a system.
Designers typically create their model diagrams using a drawing editor.
However, all drawing editors require the tedious placing and manipulation of drawing shapes on the canvas. The effort and the motor coordination skills required for this activity are mostly irrelevant to the end result: unlike architectural or mechanical engineering models the appearance of a software system's model diagram is only marginally related to the quality of the represented software design.
Computer power and automatic graph drawing algorithms have now
sufficiently advanced so as to allow the automatic placement of graph
nodes on the canvas and the near optimal routing of the respective
edges. We can therefore design models using a declarative textual
representation and subsequently view, publish, and share them in
graphical form.
UMLGraph's support for
declaratively specifying class and sequence diagrams
is part of an ongoing effort aiming to support all ten types of UML diagrams.
Creating models in a declarative, textual notation offers a number of advantages.
- First of all, the model composition mechanism matches well both a programmer's high-level skills, the textual abstract formalization of concrete concepts, and the associated low-level skills, the manipulation of text using an editor and other text-based tools.
- The declarative notation, by being closer to the program's representation (the notation I experimented with is based on the Java syntax and semantics), forces the designer to distinguish between the model and the respective implementation, between the essential system characteristics and the trivial adornments.
It is more difficult for designers to get away, as they often do now, with drawing for a model a nice picture of the implementation they have in mind.
- The declarative representation is also highly malleable, the existing visual structure does not hinder drastic changes, nor is effort wasted on the tidy arrangement of graph nodes a psychological barrier against massive design refactoring.
- Declarative models are also highly automatable: they can be easily generated from even higher-level descriptions by trivial scripts and tools operating on design process inputs such as database schemas, existing code, or structured requirements documents.
- Text macro processors can be used for configuration management, while revision control and team integration activities can utilize the same proven tools and processes that are currently used for managing source code.
Thus with a tool like CVS or RCS one can keep track of design revisions, create and merge branches, and monitor model changes, while a system like CVS can allow work to be split into teams.
- Finally, the declarative approach can readily utilize existing text processing tools for tasks that a drawing editor system may not provide.
Consider how your favorite model editor handles the following tasks and how you could handle them using a simple Perl script or a text-processing pipeline applied to the declarative model specification:
- identify all classes containing a given field (as a prelude to an aspect-oriented cross-cut);
- count the total number of private fields in a given design;
- order methods appearing in multiple classes by their degree of commonality;
- identify differences between two designs.
All the above tasks can be easily performed in text files using Unix commands
such as
grep,
wc,
grep ... | sort ..., and
diff.
Class Diagrams
One specifies a class diagram using the Java syntax complemented by
javadoc
tags.
Running the UmlGraph doclet on the specification will generate
a
Graphviz (http://www.research.att.com/sw/tools/graphviz/)
diagram specification that can be automatically processed to
create Postscript, GIF, SVG, JPEG, fig, or Framemaker drawings.
The following is an example of a specification and the resulting UML class
diagram:
class Person {
String Name;
}
class Employee extends Person {}
class Client extends Person {}
|
|
Class Diagram Operations
To use UMLGraph class drawing facility you need to have
javadoc
and
Graphviz (http://www.research.att.com/sw/tools/graphviz/)
installed on your computer.
Both programs are freely available, from Sun and AT&T respectively,
for many platforms including Unix and Windows.
UMLGraph's input follows the Java syntax and semantics.
However,
since the main purpose of UMLGraph is the declarative specification of
UML diagrams there is no need to flesh-out each class's methods,
to completely specify each class, or to specify package information.
You only specify the details you want to appear on the graph.
If you wish your (Java) implementation to evolve together with the
design feel free to include code or additional details.
You can hide these details from the UML diagram using the javadoc
@hidden
tag applied to classes, methods, and fields.
In theory you can also use UMLGraph to reverse engineer existing
Java code.
Note however that UMLGraph is not designed for this purpose;
the resulting graphs may be large and unwieldy.
UMLGraph is implemented as a javadoc doclet (a program satisfying the
doclet API that specifies the content and format of the output
generated by the javadoc tool).
Javadoc is part of the Sun JDK, so a typical JDK installation will also
include javadoc.
Before running javadoc you need to place the UmlGraph.jar
file in a location accessible by javadoc
(e.g. the Java class path or the current directory).
You then run javadoc with arguments -doclet UmlGraph
-docletpath /path/to/UmlGraph.jar
and append at the end the file(s) that contain your diagram
specification.
You can of course use any of the javadoc general options;
-private
is usually needed to avoid having to explicitly
specify public elements.
Specifying some packages before the list of source files will designate
those packages as local.
When you specify a package list,
the SVG output UmlGraph generates will contain
local hyperlinks for the local classes
and hyperlinks to the Sun Java API documentation for all other classes.
Example:
javadoc -docletpath UmlGraph.jar -doclet UmlGraph -private Simple.java
javadoc will create by default a file named graph.dot
in the current directory; option to
this is a text file that can be processed by the Graphviz
dot program to layout and draw the graph.
A command line like the following will convert the graph.dot
file into Postscript:
dot -Tps -ograph.ps graph.dot
Refer to the dot documentation for information on creating other file formats
or adjusting the UMLGraph output.
Note that when you use dot for generating SVG diagrams your
should specify the -outputencoding UML8
option to UMLGraph.
This option will correctly render the stereotype guillemot characters
in the dot output and the corresponding SVG file.
Class Modelling
The UMLGraph class diagrams allows you to model
- classes (specified as Java classes)
- attributes (specified as Java class fields)
- operations (specified as Java class methods)
- stereotypes (using the
@stereotype
name tag)
- tagged values (using the
@tagvalue
name value tag)
- implementation relationships (specified using the Java
implements
declaration)
- generalization relationships (specified using the Java
extends
declaration or (for multiple inheritance) the javadoc @extends
tag)
- association relationships (specified using the javadoc
@assoc
tag)
- navigatable (directed) association relationships (specified using the javadoc
@navassoc
tag)
- aggregation relationships (specified using the javadoc
@has
tag)
- composition relationships (specified using the javadoc
@composed
tag)
- dependency relationships (specified using the javadoc
@depend
tag)
All relationship tags appart from @extends
take four arguments:
- The source adornments (role, multiplicity, and visibility)
- The relationship name
- The target adornments (role, multiplicity, and visibility)
- The target class
Arguments can be space-separated, or enclosed in quotes if they
need to contain the space character.
The - character is used as a placeholder to denote empty arguments.
You can use the \n sequence to separate the first three adornments
in separate centered lines;
the \l and \r sequences can also be used to generate left and right
aligned lines.
You can use the < and > characters in the relationship name
to enclose stereotype names.
These will be automatically enclosed in guillemots.
Note that a relationship's target class is not implicitly
defined; it should also be specified using the Java class syntax.
The following is an example of a relationship
specification and the resulting UML diagram:
class Tyre {}
class Engine {}
class Body {}
/**
* @composed 1 - 4 Tyre
* @composed 1 - 1 Engine
* @composed 1 - 1 Body
*/
class Car {}
|
|
Class Diagram Options
A number of command-line options contol the operation of UMLGraph
class diagram generator:
- -output
- Specify the output file name (default
graph.dot
).
- -outputencoding
- Specify the output encoding character set (default
ISO-8859-1
).
When using dot to generate SVG diagrams you should specify
UTF-8
as the output encoding, to have guillemots correctly
appearing in the resulting SVG.
- -qualify
- Produce fully-qualified class names.
- -horizontal
- Layout the graph in the horizontal direction.
- -attributes
- Show class attributes (Java fields)
- -operations
- Show class operations (Java methods)
- -constructors
- Show a class's constructors
- -visibility
- Adorn class elements according to their
visibility (private, public, protected)
- -types
- Add type information to attributes and operations
- -all
- Same as
-attributes
-operations
-visibility
-types
- -nodefillcolor
- Specify the color to use to fill the shapes.
- -nodefontname
- Specify the font name to use inside nodes.
- -nodefontabstractname
- Specify the font name to use
inside abstract class nodes.
- -nodefontsize
- Specify the font size to use inside nodes.
- -nodefontcolor
- Specify the font color to use inside nodes.
- -edgefontname
- Specify the font name to use for edge labels.
- -edgefontsize
- Specify the font size to use for edge labels.
- -edgefontcolor
- Specify the font color to use for edge labels.
- -edgecolor
- Specify the color for drawing edges.
- -bgcolor
- Specify the graph's background color.
- -hide
- Specify entities to hide from the graph.
Matching is done against the end of each entity's name.
For instance, "
-hide Widget
" would hide "com.foo.widgets.Widget
" and
"com.foo.widgets.BigWidget
".
- -apidocroot
- Specify the URL that should be used as the "root" for local classes.
This URL will be used as a prefix, to which the page name for the local class or
package will be appended (following the JavaDoc convention).
For example, if the value
http://www.acme.org/apidocs
is
provided, the class org.acme.util.MyClass will be mapped to the URL
http://www.acme.org/apidocs/org/acme/util/MyClass.html
.
This URL will then be added to .dot diagram and can be surfaced in the
final class diagram by setting the output to SVG, or by creating an HTML page
that associates the diagram static image (a .gif or .png) with a client-side
image map.
- -apidocmap
- Specify the file name of the URL mapping table.
The is a standard Java property file, where the property name is a regular
expression (as defined in the java.util.regex package) and the property value is
an URL "root" as described above.
This table is used to resolved external class names (class names that do not
belong to the current package being processed by UMLGraph). If no file is provided,
external classes will just be mapped to the on-line Java API documentation.
- -noguillemot
- Specify that guillemot characters should not
be used to denote special terms like "interface" and stereotype names.
This is used on some platforms to circumvent problems associated
with displaying non-ASCII characters.
All colors can be either a symbolic name (e.g. blue),
a tripple specifying hue-saturation-brightness as values 0-1
(e.g. ".13 0.9 1"),
or a tripple specifying red-green-blue values as hexadecimal
digits prefixed by a # (e.g. "#ff8020").
The symbolic color names are derived from the X Windows System;
you can find a complete list in the Graphviz documentation.
Font names are passed directly to the dot graph generation back-end.
In general the Postcript standard names Times, Helvetica, Courier, and
Symbol are safe to use.
Since the options are really a part of the generated graph you
want in many cases to include them in the diagram specification.
You can do that by adding javadoc @opt
tags in front
of a class named UMLOptions
, as in the following example:
/**
* @opt horizontal
* @opt all
* @hidden
*/
class UMLOptions {}
You can also change the UMLGraph operation on a per-class basis by
using @opt
attributes on individual classes.
In this case the @opt
specification temporarily overrides
the particular global setting for the class being processed.
Class Diagram Example: Generalisation Relationships
/*
* Generalisation
* UML User Guide p. 141
*/
/* Basic categorisations */
class Asset {}
class InterestBearingItem {}
class InsurableItem {}
/* Asset types */
/**
* @extends InsurableItem
* @extends InterestBearingItem
*/
class BankAccount extends Asset {}
/** @extends InsurableItem */
class RealEstate extends Asset {}
class Security extends Asset {}
/* Securities */
class Stock extends Security {}
class Bond extends Security {}
/* Bank accounts */
class CheckingAccount extends BankAccount {}
class SavingsAccount extends BankAccount {}
|
|
Class Diagram Example: Advanced Relationships
/*
* Advanced relationships
* UML User Guide p. 137
*/
/**
* @opt attributes
* @opt operations
* @hidden
*/
class UMLOptions {}
class Controller {}
class EmbeddedAgent {}
class PowerManager {}
/**
* @extends Controller
* @extends EmbeddedAgent
* @navassoc - - - PowerManager
*/
class SetTopController implements URLStreamHandler {
int authorizationLevel;
void startUp() {}
void shutDown() {}
void connect() {}
}
/** @depend - <friend> - SetTopController */
class ChannelIterator {}
interface URLStreamHandler {
void OpenConnection();
void parseURL();
void setURL();
void toExternalForm();
}
|
|
Class Diagram Example: Schema
/*
* Schema model
* UML User Guide p. 112
*/
/**
* @opt operations
* @opt attributes
* @opt types
* @hidden
*/
class UMLOptions {}
/* Define some types we use */
/** @hidden */
class Name {}
/** @hidden */
class Number {}
/**
* @has 1..* Member * Student
* @composed 1..* Has 1..* Department
*/
class School {
Name name;
String address;
Number phone;
void addStudent() {}
void removeStudent() {}
void getStudent() {}
void getAllStudents() {}
void addDepartment() {}
void removeDepartment() {}
void getDepartment() {}
void getAllDepartments() {}
}
/**
* @has 1..* AssignedTo 1..* Instructor
* @assoc 1..* - 1..* Course
* @assoc 0..* - "0..1 chairperson" Instructor
*/
class Department {
Name name;
void addInstructor() {}
void removeInstructor() {}
void getInstructor() {}
void getAllInstructors() {}
}
/**
* @assoc * Attends * Course
*/
class Student {
Name name;
Number studentID;
}
class Course {
Name name;
Number courseID;
}
/**
* @assoc 1..* Teaches * Course
*/
class Instructor {
Name name;
}
|
|
Class Diagram Example: Element Visibility
/**
* Attribute and operation visility
* UML User Guide p. 123
*
* @opt operations
* @opt attributes
* @opt types
* @opt visibility
* @hidden
*/
class UMLOptions {}
/** @hidden */
class Tool {}
class Toolbar {
protected Tool currentSelection;
protected Integer toolCount;
public void pickItem(Integer i) {}
public void addTool(Tool t) {}
public void removeTool(Integer i) {}
public Tool getTool() {}
protected void checkOrphans() {}
private void compact() {}
}
|
|
Class Diagram Example: Association Types
/**
* Associations with visibility
* UML User Guide p. 145
*
* @opt horizontal
* @hidden
*/
class UMLOptions {}
/** @assoc * - "*\n\n+user " User */
class UserGroup {}
/** @navassoc "1\n\n+owner\r" - "*\n\n+key" Password */
class User{}
class Password{}
|
|
Class Diagram Example: Real Example (Catalina Classes)
/*
* Interface and generalization relationships in Jakarta Catalina
*/
class HttpResponseBase
extends ResponseBase
implements HttpResponse, HttpServletResponse {}
abstract class HttpResponseWrapper
extends ResponseWrapper
implements HttpResponse {}
class HttpResponseFacade
extends ResponseFacade
implements HttpServletResponse {}
abstract class ResponseWrapper implements Response {}
abstract interface HttpResponse extends Response {}
abstract class ResponseBase implements Response, ServletResponse {}
abstract interface HttpServletResponse {}
class ResponseFacade implements ServletResponse {}
abstract interface ServletResponse {}
abstract interface Response {}

Class Diagram Example: Class Stereotypes and Tagged Values
/*
* Class stereotypes and tagged values
* UML User Guide p. 439
*/
/**
* @opt attributes
* @opt operations
* @opt types
* @hidden
*/
class UMLOptions {}
/** @hidden */
class Action {}
/**
* @stereotype container
* @tagvalue version 3.2
*/
class ActionQueue {
void add(Action a) {};
/** @tagvalue version 1.0 */
void add(Action a, int n) {};
void remove(int n) {};
/** @stereotype query */
int length() {};
/** @stereotype "helper functions" */
void reorder() {};
}
|
|
Class Diagram Example: Colors, Global and Local Options
/**
* @opt edgecolor "yellow"
* @opt nodefontname "Times"
* @opt bgcolor ".7 .9 1"
* @opt nodefillcolor "#a0a0a0"
* @opt nodefontsize 14
* @hidden
*/
class UMLOptions{}
/**
* @opt nodefontname "Helvetica-Bold"
* @opt nodefontcolor "white"
* @composed - - - Red
* @composed - - - Green
* @composed - - - Blue
* @opt attributes
* @opt visibility
* @opt types
*/
class Pixel {
private int x, y;
public void setColor(ColorValue v) {}
}
/** @opt nodefillcolor red */
class Red {}
/** @opt nodefillcolor green */
class Green {}
/** @opt nodefillcolor blue */
class Blue {}
/** @hidden */
class ColorValue{}
|
|
Class Diagram Example: Multiple Views
Vadim Nasardinov noted that an advantage of UMLGraph over many
GUI-oriented UML drawing tools is the ability
to generate different views of a diagram
from the same source description.
The following two diagrams were generated from the same source;
a Makefile illustrates a way to organize this process.
Class Overview
Detailed Class View
Java Description
// Author: Vadim Nasardinov
// Version: $Id: //users/vadim/docs/uml/notes/diagrams/jdo/class/Root.java#2 $
import java.util.List;
import java.util.Map;
/**
* @assoc "1..1" - "0..n" Adapter
* @assoc "" - "0..n" ObjectType
* @assoc "" - "0..n" ObjectMap
* @assoc "" - "0..n" Table
* @assoc "" - "0..n" DataOperation
**/
class Root {
private Map m_adapters;
private List m_types;
private List m_maps;
private List m_tables;
private List m_ops;
public Adapter getAdapter(Class klass) {}
}
class Adapter {
public Root getRoot();
}
abstract class Element {
Root getRoot() {}
}
class ObjectType extends Element {}
/**
* @has "1..1" - "1..1" ObjectType
**/
class ObjectMap extends Element {
private ObjectType m_type;
}
class Table extends Element {}
class DataOperation extends Element {}
Makefile
# Author: Vadim Nasardinov (vadimn@redhat.com)
# Since: 2004-05-26
# Version: $Id: //users/vadim/docs/uml/Makefile#16 $
# Requires: graphviz
# Requires: transfig
# Requires: libxslt
# Requires: javac
# Requires: javadoc
# Requires: JAVA_HOME/lib/tools.jar
.PHONY : clean all build jar dot png debug
BUILD=build
jar_dir:=$(BUILD)/jars
diagrams := notes/diagrams
java_files := $(shell find $(diagrams) -name *.java)
dot_files := $(subst .java,.dot,$(java_files))
dot_files := $(foreach dot, $(dot_files), $(BUILD)/$(dot))
dot_files += $(subst .dot,-small.dot,$(dot_files))
png_files := $(subst .dot,.png,$(dot_files))
fig_files := $(shell find $(diagrams) -name *.fig)
png_files += $(subst .fig,.png,$(foreach fig, $(fig_files), $(BUILD)/$(fig)))
premade_src_png := $(shell find $(diagrams) -name *.png)
png_files += $(foreach png, $(premade_src_png), $(BUILD)/$(png))
xml_files:=$(shell find notes -name *.xml)
html_files:=$(subst notes/,$(BUILD)/notes/,$(xml_files))
html_files:=$(subst .xml,.html,$(html_files))
stylesheet:= notes/notes.xsl
javac_dest:=$(BUILD)/classes
classpath:=
javac=javac -classpath $(JAVA_HOME)/lib/tools.jar -d $(javac_dest)
timestamp:=$(BUILD)/.timestamp
uml_graph:=$(jar_dir)/UmlGraph.jar
jd:=javadoc
jd_flags := -docletpath $(uml_graph) -doclet UmlGraph -private
jd_flags += -nodefontname luxisr -nodefontabstractname luxisri
jd_flags += -edgefontname luxisr
jd_flags += -nodefontsize 8 -edgefontsize 8
jd_flags += -nodefillcolor LemonChiffon
detailed_flags := -attributes -operations -types
all: doc
clean:
rm -rf $(BUILD)
jar: $(uml_graph)
build: $(timestamp)
$(timestamp): src/UmlGraph.java
mkdir -p $(javac_dest)
$(javac) $?
touch $(timestamp)
$(uml_graph): $(timestamp)
mkdir -p $(jar_dir)
jar cf $(uml_graph) -C $(BUILD)/classes .
jar i $(uml_graph)
build/%.dot : %.java $(uml_graph)
mkdir -p $(dir $@)
$(jd) $(jd_flags) $(detailed_flags) -output $@ $<
build/%-small.dot : %.java $(uml_graph)
mkdir -p $(dir $@)
$(jd) $(jd_flags) -output $@ $<
%.png : %.dot $(uml_graph)
dot -Nheight=0.2 -Elabelfontcolor=DarkSlateBlue -Elabelfontsize=8 -Tpng -o $@ $<
build/%.png : %.fig
mkdir -p $(dir $@)
fig2dev -L png -S 4 $< $@
png: $(png_files)
build/%.png : %.png
mkdir -p $(dir $@)
cp $< $@
build/%.html: %.xml $(stylesheet)
mkdir -p $(dir $@)
xsltproc -o $@ $(stylesheet) $<
doc: $(html_files) $(png_files)
debug:
@echo $(dot_files)
Sequence Diagrams
One specifies a sequence diagram using pic macros to define
objects and method invocations.
The GNU plotutils (http://www.gnu.org/software/plotutils/plotutils.html)
pic2plot program can then process the sequence diagram to create a
PNG, PNM, (pseudo)GIF, SVG, AI, Postscript, CGM, FIG, PCL, HPGL, Regis, or TEK
drawing.
The following is an example of a specification and the resulting UML sequence
diagram:
.PS
copy "sequence.pic";
# Define the objects
object(O,"o:Toolkit");
placeholder_object(P);
step();
# Message sequences
active(O);
step();
active(O);
message(O,O,"callbackLoop()");
inactive(O);
create_message(O,P,"p:Peer");
message(O,P,"handleExpose()");
active(P);
return_message(P,O,"");
inactive(P);
destroy_message(O,P);
inactive(O);
# Complete the lifelines
step();
complete(O);
.PE
|
|
The diagram is drawn from its source code specification using a command
like:
pictplot -Tgif FILENAME.pic >FILENAME.gif
Syntax of Sequence Diagram Definitions
Sequence diagrams consist of objects, their lifelines
(also known as smimming lanes),
and the exchanged messages.
Sequence diagrams are defined in UMLGraph using the pic
syntax.
A sequence diagram file must start with the sequence:
.PS
copy "sequence.pic";
The .PS
marks the beginning of pic commands.
The sequence
copy "sequence.pic";
loads the macros defining the sequence diagram operations.
The file sequence.pic
, part of the UMLGraph distribution,
must exist in the directory where pic2plot will be executed.
Sequence diagram files must end with the sequence:
.PE
The sequence diagrams are defined by calling function-like pic
macros.
Each function call is terminated with a semicolon.
Space is not significant between macro calls; on the other hand
adding a space character between a macro's arguments can lead
to surprises and should be avoided.
Objects are referenced using variable-like alphanumeric identifiers.
Strings are enclosed in double quotes.
As an example, the following defines an object O
that will be identified in the diagram as
o:Toolkit
object(O,"o:Toolkit");
Comments start with a #
character.
# This is a comment
Defining a Simple Sequence Diagram
A sequence diagram is defined in three main phases:
- Object definition
- Message exchange
- Object lifeline completion
The following is an example of a very simple UMLGraph
sequence diagram
(from now on we will ommit the .PS/.PE
and
copy "sequence.pic";
elements.)
.PS
copy "sequence.pic";
# Object definition
object(S,"s:Switch");
object(P,"p:Pump");
# Message exchange
message(S,P,"run()");
message(S,P,"stop()");
# Object lifeline completion
complete(S);
complete(P);
.PE
The above code, defines two objects, S and P,
labeled as "s:Switch" and "p:Pump".
Objects are placed in the diagram from left to right, in the
order they are defined.
All defined objects are initially inactive.
The code then sends a messages from S to P labeled "run()",
and another one labeled "stop()".
Each message automatically advances the sequence diagram timeline by a
single step.
Finally, the code completes the lifelines of the two objects.
The resultant diagram is
An Improved Sequence Diagram
Let us try to improve the simple sequence diagram.
# Object definition
object(S,"s:Switch");
object(P,"p:Pump");
step();
active(S);
active(P);
# Message exchange
message(S,P,"run()");
message(S,P,"stop()");
# Object lifeline completion
step();
complete(S);
complete(P);
Here, we have manually advanced the timeline of our diagrams
with a step();
call after we defined the objects,
to provide them with a bit of breathing space.
We also added a similar step call at the end of the diagram.
Finally, we made both objects active, after their definition.
Calling active on a given object will change the drawing of its
lifeline, from the dashed format indicating an inactive object,
to a thick swimming-lane, active object, format.
The resultant diagram is
Creating and Destroying Objects
Objects do not always appear at the top of a UML sequence diagram;
they are often constructed by other objects.
In this case, a placeholder object is defined at the beginning
of the diagram, to leave the appropriate space of the object.
Later a create message will actually create an object with the
given label.
Any object can also receive a destroy message, that will stop
its life.
The lifeline of destroyed messages is not typically completed.
The following definition extends our previous diagram with a
dynamically created flow object.
# Define the objects
object(S,"s:Switch");
object(P,"p:Pump");
placeholder_object(F);
step();
active(S);
active(P);
# Message sequences
message(S,P,"run()");
create_message(P,F,"f:Flow");
active(F);
message(S,P,"stop()");
destroy_message(P,F);
# Object completion
step();
complete(S);
complete(P);
The resultant diagram is
Sequence Diagram Operations
The following calls can be used to define a sequence diagram.
- object(name,label);
- Defines an object with the given name, labeled on the diagram
as specified.
- placeholder_object(name)
- Defines a place where the named object will later be
created.
Can also be written as
pobject
.
- actor(name,label);
- Defines an actor with the given name, labeled on the diagram
as specified.
Actors are typically used instead of objects to indicate operations
initiated by human actions.
- complete(name);
- Completes the lifeline of a given object (or actor)
by drawing its lifeline to the bottom of the diagram.
- message(from_object,to_object,label)
- Draws a message between two objects, with the given label.
Self messages (where an objects sends a message to itself)
are supported.
- return_message(from_object,to_object,label)
- Draws a return message between two objects, with the given label.
Can also be written as
rmessage
.
- create_message(from_object,to_object,object_label);
- Has from_object create the to_object, labeled
with object_label.
The message is labeled with the
«create»
stereotype.
Can also be written as cmessage
.
- destroy_message(from_object,to_object);
- Sends a message
labeled with the
«destroy»
stereotype
from the from_object to the to_object.
The object to_object is marked as destroyed, with an X at the
end of its lifeline.
The object's lifeline need not be otherwise completed.
Can also be written as dmessage
.
- active(object);
- Changes the object's status to active, and
changes its lifeline drawing style correspondingly.
An active call in an already active object will result
in a swimlane showing a nested object activation.
- inactive(object);
- Changes the object's status to inactive, and
changes its lifeline drawing style correspondingly.
An inactive call on a nested object invocation will
result in showing a simple active swimlane.
- delete(object);
- The object deletes itself, drawing an X at the end
of its lifeline.
The object's lifeline need not be otherwise completed.
- lifeline_constraint(object,label);
- Displays a constraint label (typically given inside curly braces)
for the given object.
The constraint will appear on the right of the object's lifeline
at the time it appears.
Can also be used to place an message label on the left of a
message arrow, rather than its center.
Can also be written as
lconstraint
.
- object_constraint(label)
- Displays an object constraint (typically given inside curly braces)
for the last object defined.
Can also be written as
oconstraint
.
- step();
- Steps the time by a single increment, extending all
lifelines.
- async();
- All subsequent messages are asynchronous and will
be drawn correspondingly.
- sync();
- All subsequent messages are synchronous and will
be drawn correspondingly.
Sequence Diagram Variables
The value of
pic variables can sometimes be modified by assignment
to achieve a better-looking result.
The following two lines change the width of the object boxes to
1.1" and the spacing between objects
to 0.5".
boxwid = 1.1;
movewid = 0.5;
The following variables can be redefined to change the layout of
a drawing.
Variable Name | Default Value | Operation |
boxht | 0.3 | Object box height |
boxwid | 0.75 | Object box width |
awid | 0.1 | Active lifeline width |
spacing | 0.25 | Spacing between messages |
movewid | 0.75 | Spacing between objects |
dashwid | 0.05 | Interval for dashed lines |
maxpswid | 11 | Maximum width of picture |
maxpsht | 11 | Maximum height of picture |
Sequence Diagram Example: Nested Activation and Complex Interactions
The following diagram, based on the one appearing on p. 436 of the
UML User Guide, contains the most important elements
of an interaction.
It also uses nested
active inactive calls to show a nested object activation.
Diagram
Diagram Source Code
# UML User Guide: Appendix A,p. 436
.PS
copy "sequence.pic";
# Define the objects
pobject(E,"External Messages");
object(T,"t:thread");
object(O,":Toolkit");
pobject(P);
step();
# Message sequences
message(E,T,"a1: run(3)");
active(T);
message(T,O,"run()");
active(O);
message(O,O,"callbackLoop()");
cmessage(O,P,"p:Peer"," ");
active(O);
message(O,P,"handleExpose()");
active(P);
rmessage(P,O,"");
inactive(P);
inactive(O);
dmessage(O,P);
inactive(T);
inactive(O);
step();
complete(T);
complete(O);
.PE
Sequence Diagram Example: Concurrent Processes and Activations
The following diagram, based on the diagram appearing on p. 70 of
UML Distilled, contains self calls, object activation,
self-deleted objects, and asynchronous messages.
Diagram
Diagram Source Code
# UML Distilled: Figure 5-2 p. 70
.PS
copy "sequence.pic";
boxwid = 1.3;
# Define the objects
pobject(X);
pobject(T);
pobject(C);
pobject(A1);
pobject(A2);
# Message sequences
cmessage(X,T,"a: Transaction");
active(T);
async();
cmessage(T,C,"a: TransCoord");
inactive(T);
active(C);
cmessage(C,A1,"a1: TransCheck");
active(A1);
cmessage(C,A2,"a2: TransCheck");
active(A2);
message(A1,C,"ok");
sync();
step();
active(C);
message(C,C,"all done?");
inactive(C);
async();
step();
delete(A1);
inactive(C);
step();
message(A2,C,"ok");
active(C);
sync();
step();
active(C);
message(C,C,"all done?");
inactive(C);
async();
step();
delete(A2);
message(C,T,"beValid");
inactive(C);
active(T);
step();
complete(T);
complete(C);
.PE
Sequence Diagram Example: Create and Destroy
The following diagram, based on the one appearing on p. 247 of the
UML User Guide, illustrates the dynamic creation and destruction of
objects, an object constraint, and the changing of the focus of control.
Diagram
Diagram Source Code
# UML User Guide: Figure 18-2
.PS
copy "sequence.pic";
boxwid = 1.1;
movewid = 0.5;
# Define the objects
object(C,"c:Client");
pobject(T);
object(P,"p:ODBCProxy");
# Message sequences
step();
active(C);
cmessage(C,T,":Transaction");
oconstraint("{Transient}");
step();
message(C,T,"setActions(a,d,o)");
active(T);
message(T,P,"setValues(d,3.4)");
active(P);
step();
inactive(P);
message(T,P,"setValues(a,\"CO\")");
active(P);
rmessage(T,C,"committed");
inactive(T);
inactive(P);
async(); dmessage(C,T);
step();
inactive(C);
step();
complete(C);
complete(P);
.PE
Sequence Diagram Example: Lifeline Constraints
The following diagram, based on Figure 18-4 appearing on p. 252 of the
UML User Guide, illustrates constraints on an object's lifeline,
used both as genuine constraints, and to place a message label
on a particular position.
In addition, this diagram also uses nested activation.
Diagram
Diagram Source Code
# UML User Guide: Figure 18-4
.PS
copy "sequence.pic";
movewid = 0.5;
# Define the objects
object(S,"s:Caller");
object(W,":Switch");
pobject(C);
object(R,"r:Caller");
# Message sequences
step();
active(W);
async(); message(S,W,"liftReceiver"); sync();
active(S);
message(W,S,"setDialTone()");
async(); message(S,W,"*dialDigit(d)"); sync();
lconstraint(W,"{dialing.executionTime < 30s}");
active(W);
message(W,W,"routeCalls(s,n)");
inactive(W);
cmessage(W,C,"c:Convers");
active(C);
message(C,R,"ring()");
active(R);
async(); message(R,C,"liftReceiver"); sync();
message(C,W,"connect(r,s)");
message(W,S,"connect(r)");
# Specify label as a "constraint" to allign on W
message(W,R,""); lconstraint(W,"connect(s)");
step();
complete(S);
complete(W);
complete(C);
complete(R);
.PE
Sequence Diagram Example: External Actor
The following diagram, based on Figure 7-1 appearing on p. 102 of the
UML User Guide, illustrates an interaction diagram with an
external actor.
Diagram
Diagram Source Code
# UML User Guide Figure 7-1.
.PS
copy "sequence.pic";
actor(A,"");
object(T,":OTaker");
object(F,":OFulfill");
step();
message(A,T,"submitOrder");
message(T,F,"placeOrder");
message(F,A,"acknowledgeOrder");
step();
complete(A);
complete(T);
complete(F);
.PE
Sequence Diagram Example: A DNS Query
The following diagram, illustrates the operating system calls of
a typical DNS query.
It is planned to appear in the second volume of the book
Code Reading: The Open Source Perspective (http://www.spinellis.gr/codereading).
The diagram was the original motivation behind the UMLGraph sequence diagram
drawing facility.
Diagram
Diagram Source Code
#/usr/bin/pic2plot -Tps
#
# Run as pic filename | groff | ps2eps
#
# DNS query collaboration diagram
#
# $Id: dnsq.pic 1.4 2004/04/06 08:08:24 dds Exp $
#
.PS
copy "sequence.pic";
boxwid = 1.3;
# Define the objects
object(B,":Web Browser");
object(W,":Workstation Kernel");
object(S,":Server Kernel");
object(D,":DNS Server");
step();
# Message sequences
active(B);
active(D);
active(W);
active(S);
message(D,S,"select");
inactive(D);
message(B,W,"socket");
message(B,W,"connect");
message(B,W,"sendto");
message(W,W,"send packet");
message(W,S,"DNS A query");
message(B,W,"recvfrom");
inactive(B);
message(S,S,"receive packet");
rmessage(S,D,"select returns");
active(D);
message(D,S,"recvfrom");
message(D,S,"sendto");
message(S,S,"send packet");
message(S,W,"DNS A reply");
message(W,W,"receive packet");
rmessage(W,B,"recvfrom returns");
active(B);
message(B,W,"close");
complete(B);
complete(W);
complete(S);
complete(D);
.PE
Frequently Asked Questions
Contents
Why are the SVG diagrams dot generates malformed?
UMLGraph uses guillemot characters for representing the angle brackets around
stereotypes, as in «interface».
By default these are encoded as ISO-8859-1 characters, which are illegal
in the UTF-8 output that dot generates for SVG.
When using dot to generate SVG output, you should also specify
-outputencoding utf8
to UMLGraph.
How can I improve the quality of the bitmap images I generate?
Both
dot and
pic2plot can directly produce bitmap images in
formats like GIF, PNG and PNM.
However, if you want to produce presentation-quality output
the a vector output format like Postscript or SVG is preferable.
If you do require a bitmap format, it might be worth to create
it at a higher resolution from a Postscript image, and then downsample it.
This procedure (used for the diagrams appearing on the UMLGraph web site)
will create an antialiased image of a higher quality than what the default
bitmap output options produce.
The following pipeline is an example of how you can achieve this
effect:
dot -Tps FILENAME.dot |
gs -q -r360 -dNOPAUSE -sDEVICE=pnm -sOutputFile=- - -c quit |
pnmcrop |
pnmscale 0.25 |
ppmtogif >FILENAME.gif
One other possibility for converting the sequence diagram into Postscript
is to pass it through pic and groff.
Tools like ps2epsi and ps2eps can then be used to
convert the Postscript into encapsulated Postscript.
Of course, groff users will just use the pic
program as part of their processing pipeline.
A class appears multiple times in a class diagram. Why?
Most probably your class diagram uses packages, and you are not
qualifying the classes with the respective package names in the
tags you use.
The tags are not smart enough to do the package resolution,
so you will have to prepend the package name to the class,
or avoid using packages.
Problematic Specification
package test;
abstract class AbstractNode {}
/** @composed 1 has * AbstractNode */
class InnerNode extends AbstractNode {}
class Leaf extends AbstractNode {}
First Approach: Class Name Qualified with the Package
package test;
abstract class AbstractNode {}
/** @composed 1 has * test.AbstractNode */
class InnerNode extends AbstractNode {}
class Leaf extends AbstractNode {}
Second Approach: No Package Specification
abstract class AbstractNode {}
/** @composed 1 has * test.AbstractNode */
class InnerNode extends AbstractNode {}
class Leaf extends AbstractNode {}
Shouldn't static fields appear underlined?
Yes they should.
Unfortunately, dot does not (yet) support a way to underline
single labels, and thus UMLGraph can not show the static fields
underlined.
Where can I find a pic2plot executable for Windows?
A port of pic2plot for Windows can be found in
GNU PlotUtils, which is part of the
GnuWin32 (http://gnuwin32.sourceforge.net/packages.html)
project.
Under Windows the output of pic2plot appears empty. Why?
On Windows platforms note that the current version of
pic2plot appears to be very picky about carriage return (CR - \r)
characters (by default, CR is part of the platform's end of line sequence)
appearing in its input file.
Therefore, you will probably want to instruct your editor to create
Unix-style files, or filter the files to remove the carriage return
characters.
The following Perl invocation is such a filter:
perl -p -e "BEGIN {binmode(STDOUT);} s/\r//"
You can remove the CR characters in-place by running:
perl -pi.bak -e "BEGIN {binmode(STDOUT);} s/\r//" FILENAME.pic
In addition, pic2plot appears to require that the last input file
be properly terminated (with a newline).
Apparently, some Windows editors may leave the last line unterminated,
so if your editor is in this category it may be safer to add a blank line
in the end.
I have a problem with Maven's Dotuml plugin. Can you help me?
Sorry, I did not develop this plugin, and therefore can not offer help.
Have a look at the project's documentation and mailing lists available through
plugin web page (http://maven-plugins.sourceforge.net/maven-dotuml-plugin/).
Bibliography
- Grady Booch, James
Rumbaugh, and Ivar Jacobson.
The
Unified Modeling Language User Guide.
Addison-Wesley, Reading, MA, 1999.
- Martin Fowler and
Kendall Scott.
UML
Distilled: Applying the Standard Object Modeling Language.
Addison-Wesley, Boston, MA, second edition, 2000.
- Emden R. Gasner,
Eleftherios Koutsofios, Stephen C. North, and Kiem-Phong Vo.
A technique for drawing directed graphs.
IEEE Transactions on Software Engineering, 19(3):124–230, May
1993.
- Brian W. Kernighan.
PIC—a graphics language for typesetting: Revised user manual.
Computer Science Technical Report 116, Bell Laboratories, Murray Hill, NJ,
December 1984.
Available online at http://cm.bell-labs.com/cm/cs/cstr.
- James Rumbaugh, Ivar
Jacobson, and Grady Booch.
The
Unified Modeling Language Reference Manual.
Addison-Wesley, Reading, MA, 1999.
- Diomidis Spinellis.
Code Reading: The Open
Source Perspective.
Addison-Wesley, Boston, MA, 2003.
- Diomidis Spinellis.
On the declarative specification of models (http://www.dmst.aueb.gr/dds/pubs/jrnl/2003-IEEESW-umlgraph/html/article.html).
IEEE Software, 20(2):94–96, March/April 2003.
Version History
- Version 2.10 2004/11/19
-
- Corrected the interaction between the
-attributes
and
-operations
options and classes with no
fields or methods.
Many thanks to Jonathan Wright for this contribution.
- New documentation look, designed by George Zouganelis
- This may well be the last version to run under Java 1.4.
The next version will require Java 5.0, to support the new Java
features: generics, varargs, and enums.
- Version 2.9 2004/10/07
-
- Class diagrams can now include constructors, through the new
-constructors
option.
- Version 2.8 2004/08/09
-
- Fixes to support the Maven plugin.
- From this version onward, use the appropriate options to create
documentation links; no hyperlinks are created by default.
- Version 2.7 2004/08/06
-
- The -noguillemot option will output round brackets around stereotypes,
instead of angle brackets.
The angle brackets appear to be breaking some programs.
- Version 2.6 2004/08/03
-
- Note that from this version UMLGraph requires Java 1.4.
- Documentation example: multiple views from the same source.
Many thanks to Vadim Nasardinov for this contribution.
- Documentation now includes a FAQ section.
- Documented the fact that package names must be explicitly
specified in tags. Arne Bayer noticed the associated problem.
- Correct handling of multiple space in tags.
Noted by Jeffrey M. Thompson which the help of
FindBugs (http://findbugs.sourceforge.net/).
- Completed customization of URL mapping. Now the mapping is fully
configurable and can be controlled by the use of two new options:
"-apiDocRoot" and -"apiDocMapFileName".
This change allows the creation of "clickable"
diagrams fully integrated with web-based documentation
(for example JavaDoc pages).
The upcoming UMLGraph Maven plugin will take full advantage of this feature.
Implementation contributed by Nascif Abousalh-Neto
- The -hide argument now accepts regular expressions.
- Removed copy-pasted Java code that was introduced in version 1.24.
- Some dot edges were missing a semicolon. This is now fixed.
- Version 2.5 2004/06/15
-
The object swimlanes in a sequence diagram
can now show nested object invocations.
This very useful and non-trivial change was contributed by Jonathan R. Santos.
- Version 2.4 2004/05/29
-
Will now generate local URL hyperlinks for packages specified in
the command line; and links to the Sun documentation for all
other packages.
Many thanks to Nascif Abousalh-Neto for contributing this change.
- Version 2.3 2004/05/27
-
-
Remove hardcoded default node and edge fonts.
Thanks to Vadim Nasardinov for submitting the corresponding patch.
-
Generate javadoc hyperlink paths in a directory-tree structure;
do not show arcs on hidden classes.
Thanks to Alessandro Riva for submitting the corresponding patch.
- Version 2.2 2004/05/25
-
SVG class diagrams containing guillemot characters
for stereotypes
can now be made valid through a new -outputencoding option.
Use "-outputencoding UTF-8" when using dot to generate SVG diagrams.
Many thanks to Nascif Abousalh-Neto for bringing this problem to
my attention.
- Version 2.1 2004/05/16
-
The guillemot characters used for the create and destroy stereotypes
are now portable between groff and pic2plot.
Many thanks to Scott Johnson (Duluth, MN) for recommending the change.
- Version 2.0 2004/05/09
-
- Support for drawing sequence diagrams.
- New distribution format.
- Browsable and printable documentation.
- Removed the ant-based compilation and distribution
system; it was proving a hindrance in organizing the project in
a resonable manner.
Compiling the documentation and distribution is now handled by
a (non-distributed) Makefile; the compilation process is described
in the README file.
- Version 1.24 2003/07/30
-
Changes by Art Hampton (thanks):
- Create the appropriate label for relationship tags when referring to
classes which were not parsed by javadoc.
- New "-hide <matchstring>" option, where <matchstring>
matches the end of the name of an entity.
Matched entities are removed from the graph.
A regular expression matching facility will be added when Java 1.4
becomes more widespread.
- Version 1.23 2003/05/7
-
Added
-output
command-line option, and an ant-based
build file.
Modified the dot output to avoid triggering a graphviz bug that made escape codes visible.
- Version 1.20 2003/04/25
-
Fixes by Nick Efthymiou (thanks):
will generate SVG hyperlinks to Javadoc documentation,
better handling of abstract class fonts,
and correct listing of interfaces.
- Version 1.19 2002/09/20
-
New options:
nodefontname,
nodefontabstractname,
nodefontsize,
nodefontcolor,
edgefontname,
edgefontsize,
edgefontcolor,
edgecolor,
bgcolor.
- Version 1.18 2002/08/26
-
- Can now specify class-local options.
- Support for the @tagvalue tag.
- Support for the @stereotype tag.
- Added nodefillcolor option.
- Version 1.15 2002/07/26
- First public release.
Acknowledgements
The following individuals have constributed useful comments and code.
UMLGraph would not be in its current state without their contributions.
- Nascif Abousalh-Neto
- Nick Efthymiou
- Art Hampton
- Scott Johnson
- Vadim Nasardinov
- Alessandro Riva
- Jonathan R. Santos