|
Creating Custom Model Propertiesby John Hsia
|
|
| John
Sunda Hsia is the author of the training class "Extending Rational
Rose". As a Technical Lead Engineer with the RationalLink partner
program, he manages the training support of RoseLink, RequisiteLink
Partner Program and ClearCaseLink partners in their effort to create
add-ins and integrations. John has spent almost ten years working
with visual modeling tools, object-oriented methodologies,
structured methodologies and meta-CASE tools. John can be reached at
[EMAIL PROTECTED].
|
Introduction
In the first article of the Rose Extensibility series, an architectural
overview of Rose Extensibility was presented. A natural follow-up would
have been the built-in scripting language (RoseScript) or the COM
interface (REI -Rose Extensibility Interface). Since both of these topics
are fairly fundamental and well documented, I thought it was more
appropriate to explore a more advanced and less documented topic - Custom
Model Properties.
The subject of many rose_forum1 threads and the source of
much frustration among REI users, custom model properties allow users to
extend the model information captured by Rose. Also known as UML
TaggedValues, properties are essentially name-value pairs that are
attached to model elements. By defining new properties, both users and
RoseLink2 Partners can customize Rose to address the
specialized needs of their project environment or their target language,
framework or tool. We'll begin our discussion by defining properties,
their organization and then look at some code examples for defining,
accessing and writing properties.
What are Properties?
Rather than regurgitating the UML definition for TaggedValues, let's
look at how properties are presented to the user. In figure 1, we see the specification dialog for packages.
Four package properties for the Add-In C++ are shown - IsNamespace,
Indent, CodeName and GenerateEmptyRegions. Each property is defined with a
particular type. The four types shown are Boolean, integer, string, and
user-defined enumerations. Properties are found on all model elements,
though not all model elements (e.g. operation parameters) possess a GUI
that exposes this information. Of course, these properties can always be
accessed programmatically through the REI.
Organization of Properties
Properties are grouped into record structures called Tools -
usually presented to the user as individual tabs. In Figure 1, the four properties shown belong to the tool
called "C++"3. Usually tools correspond to a Rose Add-In
but not always. Additional tabs that may appear with Rose Enterprise are
"IDL", "Java" and "Oracle8". Not all tabs are property tabs. Some
non-property tabs, such as "General", "Detail", and "Files" are used to
present other pertinent model information.
Also in Figure 1, there's a drop down list titled "Set:". For
each tool4 , users can define sets of default values for
the properties of that tool . For individual model elements, one of these
sets is referenced. Users can then choose to either leave the default
value untouched or to override this value. It is easy to determine if a
value is default or if it is overridden. In Figure 1, the fourth column in the property table shows
the source of the value (i.e. default or overridden).
Sets are provided purely as a convenience feature. Anyone who has used
the Rose C++ add-in can tell you how overwhelming and repetitious it is to
fill in the right property values for each model element. By using sets,
users can capture this repetition.
As one would expect, properties are specific to a model element. For
example, the C++ properties for a package are different than those
available for a class, attribute, or operation.
All model elements possess groupings (i.e. tools) of name-value pairs
called properties. As a convenience, users can define sets of default
values for each tool. Now we'll look at how these properties can be
defined.
Creating Custom Properties
Let's begin with a real world example. Assume that we're the toolsmiths
in a geographically distributed project. The project manager has tasked us
with extending Rose to capture quality assurance (QA) data for the
smallest versioned design artifact - as you might guess, a package.
Specifically, we need to capture the following properties:
- Owning Team - Possible values include Unassigned,
Cardassians, Klingons, Dominion, Romulans and Borg
- Approver - Name of the QA Engineer
- Passed - Has the QA Engineer approved the elements in this
package
- Rating - A value from 1 to 10 that states the confidence
level of the approver
After defining the new tool "QA" and the
above properties, the specification dialog might look like the graphic in
Figure 2. Figure 3 shows the same dialog with all possible values
for Owning Team displayed.
The source RoseScript to define the new properties is shown in Figure 4. When this code is executed in Rose, the QA tab
along with the four new properties shown in Figure 2 and 3 are immediately available on specification dialogs for
packages. Since the same REI objects and interfaces are available through
COM, similar programs could be written in any language that can access COM
(e.g. VB, C++, Java). Now let's take a detailed look at this source code
line by line.
2-3: All visible properties5 need to be defined through
property files6 or through properties and methods on the
DefaultModelProperties object ().
4-5: The name of the tool ("QA") and the set ("default") that we plan
to define.
6: A call to create DefaultPropertySet(className, toolName,
newSetName) defines the set and the tool with one call. In the REI,
packages from the Use Case View and the Logical View map to the REI COM
object called Category - hence the argument "Category" versus
"Package". Most other REI COM objects are consistently named (e.g. Class,
Attribute, Operation ...)
7: The properties of a model can be controlled and can be read-only so
we must account for that possibility.
10, 13: Line 10 defines a new data type called "TeamSet" of meta-type
"Enumeration" whereas line 13 defines the actual property called "Owning
Team" with a default value of "Unassigned". As seen in this example, the
method addDefaultProperty (className, toolName, setName, propertyName,
type, value) is overloaded. "TeamSet" is defined with its possible
values "Unassigned, Cardassians ..." separated by commas.
17: The property "Approver" of type "String" with a default value of
null string is defined.
20: The property "Passed" of type "Boolean" with a default value of
"False" is defined. The REI will automatically convert the string "False"
to a boolean.
23: The property "Rating (1-10)" of type "Integer" with a default value
of "0" is defined. The REI will automatically convert the string "0" to an
integer. Since there is no way of defining constraints for this property
(i.e. 1 <= x <= 10), we simply include the constraints as part of
the property name to help the user.
There are additional methods for manipulating the default model
properties. Check the on-line help, the Rational Rose type library or the
Rose Extensibility Interface Reference manual for all the methods of
DefaultModelProperties. Now let's take a look at how we might access these
new properties.
Accessing Properties Figure 5
Continuing with our example, the project manager has asked us to create
a checking program that reports on any package that hasn't passed or has a
rating of 5 or less. Let's take a look at what this source code might look
like.
4: For this example, the report will be written to the Rose's error
log.
5: Checking will be conducted on all packages. The method
RoseApp.CurrentModel.GetAll Categories() will return a
CategoryCollection of all the packages found in the use case view
and the logical view - including the views themselves.
6, 7: This is a collection so we do need to iterate through each item
in the collection.
8: We probably don't want to perform this check on the use case view
and the logical view. The top level categories are hardcoded.
9: Check the "Passed" property for a value of "False". A call to
getPropertyValue (tool, propertyName) returns a string value for
the property specified - regardless of the type of the property.
11: Check the "Rating (1-10)" property for values less than 5. Since
this is an integer field, an integer typecasted as a string will always be
returned. Notice that the name used to retrieve a property and the name
presented to the user are exactly the same.
Some additional methods include getToolProperties (toolName),
getAllProperties() and getCurrentProperty SetName(toolName). The first
method gets all the properties of a tool. The second method gets all
properties regardless of grouping. The last method gets the current
property set from which defaults are taken. With the first two methods, a
collection of properties will be returned. As you might guess, properties
are first class objects with attributes such as value. But rather than
just changing the value field, our next example will actually use mutator
methods.
Writing Properties Figure 6
For our final example, the project manager has asked us to modify the
previous checking program to check for illegal ratings. Specifically, any
package with ratings over the value of 10 will have its passed status and
ratings reset to False and 0 respectively. The source RoseScript for such
script might look something like the following.
9-17: Replaces line 9 of the previous example
9: Checks for illegal values
11: Changes the Passed property to False. A call to OverrideProperty
(tool, propertyName, newValue) overrides the previous value. It
doesn't matter if the previous value was a default value or if it was
already overridden.
14: Same as line 11 but for the property Rating.
In this example, property values were overridden by calling a mutator
called OverrideProperty. An alternative would have been to get the actual
property object and then just change the value attribute on it. This
approach will work but it does have its pitfalls. A property object can be
either a default value or an overridden value. Default values actually
belong to a set of defaults and are only referenced from model elements.
So changing the value field directly will also alter all its references.
This may be the desired effect but usually is not. The methods IsDefault
Property() and IsOverriddenProperty() can be used to test properties
before any direct modification. In general, it is simpler to just call
OverrideProperty. We are guaranteed that the default value for other model
elements remains the same.
Distributing Custom Properties
So how does one deliver custom properties? If you're creating an
add-in, then the registry settings for the Rose add-in would simply
reference a property file6 that defines these properties. I'll save this
discussion about add-ins and about property files for a later article.
Using what you now know, these properties were defined via COM calls. So I
would recommend distributing a clean model file modified with your
properties. The recommended steps would be:
1. Open Rose with a clean model file.
2. Execute your RoseScript that defines these new properties
3. Save this model out.
Now simply give this model file to your users as the model file to use
as their base model. Of course, this method is not automatic and can be
prone to errors. Alternatively, if you happen to have access to the
Framework Wizard, then follow the simple steps within the wizard itself to
define a new framework. Once this is done, your users will see your
framework along with various Java and C++ frameworks that Rational
Software distributes with Rose.
Summary
Out-of-the-Box, Rose provides a generic UML platform for capturing
modeling information. As useful as analysis and design may be, the ability
to capture information specific to your process, your development
environment, your target language, or framework can make Rose an even more
productive tool.
With only slight modifications to the first example, you can create
your own tools/tabs of properties to capture pertinent data such as:
- metrics
- project estimation
- requirements
- code generation options
Automagically, the specification
dialogs for model elements will expose your custom properties for users to
view and modify. Then, by understanding the second and third examples, you
can gather that data through REI COM objects from any COM enabled language
to drive reports, spreadsheets, other tools, and even code generation.
With the same capability as Rational Software's developers and its 90+
RoseLink Partners, now you'll be able to tailor Rose to fit your specific
needs.
Footnotes
1. rose_forum is an e-mail based forum for Rational Rose related
technical issues. This e-mail list is open to all parties. To subscribe,
simply send an e-mail to [EMAIL PROTECTED] with the body "subscribe
rose_forum".
2. RoseLink Partner Program is a marketing program designed to
encourage and support the creation of Add-Ins for Rational Rose. For more
details, check out www.rational.com/partners/rationallink/ roselink/
3. Actually, the tool is called "cg" not "C++". Tool registry settings
allow add-ins to define an optional pretty name for a tool. This
essentially changes what the user sees. Any programs written to access
properties in this tool would still have to use the real name - i.e. "cg".
4. Typically, this is done within Rose's user interface - the "Edit
Set" button in the specification dialog, the menu option Tools/Model
Properties/Edit or F4.
5. Visible properties are those that can be viewed and modified via the
specification dialog. Not all properties are visible. For example, on
model elements, the CreateProperty() method can result in invisible
properties that are persistent but not seen by the user.
6. Property files are usually seen as *.pty files within an add-in's
installation directory. At this point in time, property files are only
addressed within the "Extending Rational Rose" training class. Property
files will be addressed in a later article.
Back
to Contents
Copyright � 1999
Rational Software and
Miller Freeman, Inc., a United News & Media
company.