TextUML Toolkit Documentation - Back to main page
This document is a primer on the following UML features and how they are supported in TextUML:
One weird thing about UML is that there aren’t collection types or array types. Basically, multiplicity and typing are totally independent concerns, represented by the metaclasses TypedElement and MultiplicityElement.
A typed element is a named element that has a type, and that is all about it. Examples of typed elements are value specifications, properties, parameters, pins and variables.
A multiplicity element, on the other hand, is an element that when instantiated potentially admits a collection of values. An optionally defined lower bound value (defaults to 1) can determine the minimum number of instances expected. Whether multiple values are in fact admitted will depend on the upper bound of the multiplicity element, which defaults to 1 (no multiple values allowed), but can be set to any positive integer, or infinity. A multiplicity element that can actually be multivalued can also be characterized regarding ordering (whether values can be accessed by position) and uniqueness (whether values can be repeated).
Some kinds of elements are both typed and support multiplicity (such as properties, parameters, pins and variables), however a few are one or the other (let’s ignore those in this discussion).
To try to illustrate all that was said above, let’s see a few examples of Java variable declarations and the equivalent declaration in UML (using TextUML syntax):
declaration | Java | TextUML |
---|---|---|
single-valued | Client c | c : Client |
multi-valued | Collection |
c : Client[*] {unique} |
ordered | List |
c : Client[*] {ordered} |
unique | Set |
c : Client[*] {unique} |
optional | Optional |
c : Client[0, 1] |
There are few interesting differences though:
There are some implications related to assignment when the source and destination are multiplicity elements:
Profiles and stereotypes form a lightweight mechanism for extending the UML metamodel.
A stereotype allows you to tag elements in your model so they can be interpreted differently from ordinary model elements, much like annotations work in languages such as C# and Java. These tags can then be used to drive code generation, for example, so for every class marked as “persistent”, appropriate persistence code should be generated.
A profile is a special kind of package intended to contain stereotype declarations that extend UML to cover some specific domain or platform.
Let’s see how to declare and use profiles and stereotypes with the help of the TextUML Toolkit.
To declare a stereotype in TextUML, one uses the following syntax:
profile <profile-name>;
stereotype <stereotype-name> extends <metaclass-1 [,...metaclass-n]...]
[<property-1>; [... property-n;]...]
end;
end.
In other words, a stereotype can be declared as applicable to one or more metaclasses (i.e. types of elements in a UML model), and a stereotype can optionally declare properties (more on properties later) . For instance, a class could be tagged with the <<persistent>> stereotype:
profile business_apps;
import uml;
stereotype persistent extends Class
end;
end.
Or operations could be marked as <<transactional>>, meaning that a transaction will be started whenever the operation starts executing, and finished when its execution ends:
profile business_apps;
import uml;
stereotype transactional extends Operation
end;
end.
Any UML element can be affected by stereotypes, but stereotypes are declared as targetting (potentially multiple) specific element types. For instance, the UML specification has an example of a profile for Enterprise JavaBeans that defines a <<Session>> stereotype for session beans. The<<Session>> stereotype declares a property that allows modelers to define whether the session bean component is stateful or stateless.
profile EJB;
enumeration StateKind
STATELESS, STATEFUL
end;
stereotype Bean extends uml::Component
end;
stereotype Session specializes Bean
property kind : StateKind;
end;
stereotype Entity specializes Bean
end;
end.
Now that we know how to declare stereotypes, lets see how to use them. First of all, you must apply the profile defining the stereotypes to the model declaring elements you want to apply stereotypes to:
model bank;
apply business_apps;
/* other model elements here */
end.
You can then attach stereotypes defined in the applied profile to the suitable model elements in your model:
model bank;
apply business_apps;
[persistent]
class Account
attribute accountNumber : base::String;
attribute balance : base::Real;
attribute changes : AccountChange[0,*];
[transactional] operation withdraw(amount : Real);
[transactional] operation deposit(amount : Real);
operation balance() : Real;
[transactional] operation transfer(other : Account, amount : Real);
end;
end.
In the example above, we applied the <<persistent>> stereotype to the Bank class, and the <<transactional>> stereotype to the withdraw, deposit and transfer operations. In order to have access to these stereotypes, we had to apply the “business_apps” profile to our model.
In this article, we saw how to declare stereotypes and apply them to elements in UML models. We learned that a stereotype must explicitly declare the metaclasses they are applicable to, and that optionally stereotypes might declare properties. Finally, we saw that before a stereotype can be used in a model, the profile declaring the stereotype must be applied to the model.
One of the least known and understood concepts of UML is templates. Section 17.5 on version 2.1.1 of the UML specification covers the Templates package in 31 pages. What follows is an attempt at providing a summary of the mechanism in a way that is easy to understand without actually omitting any important details.
The following example in TextUML should be easy to understand for any developer familiar with C++ parametrized types or Java generics:
class Foo
end;
class Bar<T>
attribute prop1 : T;
operation op11(par1 : T);
end;
class Fred
attribute attr1 : Bar<Foo>;
end;
Class ‘Bar’ is a template class, whose template signature contains a single parameter: ‘T’. The type of the property ‘prop1′ is defined as the template parameter ‘T’. Class ‘Fred’ declares ’someOp1′, an operation that takes a parameter whose type is a binding of the template class ‘Bar’. ‘Bar’’s template parameter ‘T’ is bound to the class ‘Foo’. Implicitly, the type of ‘Fred.attr1′ when expanded against Foo should look something like:
class BarOfFoo
attribute prop1 : Foo;
operation op11(par1 : Foo);
end;
Note that the expanded class has actually no name, but I am calling it ‘BarOfZoo’ for pedagogical reasons.
Would you like to play with templates in UML? There is some support for templates in the TextUML Toolkit since M2, but it is, to put it mildly, not fully baked.