Purpose – To provide support for the use, definition and
management of UML profiles with ArgoUML.
The Profile subsystem is located in the package
org.argouml.profile and its sub-packages.
In package org.argouml.profile there are classes that
define almost all the subsystem API, concerning the definition and management
of UML profiles.
The package org.argouml.profile.init contains the
remaining subsystem API, being its only purpose to provide the subsystem
initialization API (this is therefore of use only to a minority of other
subsystems).
The profile subsystem is similar in some ways to the model subsystem –
there is a ProfileFacade that is the main entry point
to the methods and classes that provide management functions to the subsystem
(notably the ProfileManager).
It also maintains a one to one relationship with the remaining subsystems of
ArgoUML, although it is not Singleton based in order to facilitate testing
and easy cleanup or reset of its internal state.
This section which describes the Profile subsystem is organized according to
the main usages of it from a point of view of programming.
We hope that it provides guidance for the developers that want to write code
that interacts with this subsystem, but, we also try to provide enough
internal design information that it serves as an invitation for those same
developers to delve, enhance and fix!
Therefore we have the following sub-sections:
Section 5.7.1, “Initialization of the profile subsystem” –
describes how to initialize the subsystem or the related issue how to
re-initialize the subsystem and what does that mean to your profiles.
Section 5.7.2, “Profile(s) management” –
describes the API involved in the management of the profiles and some
classes related to this, even if these aren't in the Profile subsystem.
This is probably the most interesting section for the majority of the readers
since it goes well inside the guts of the subsystem, as well as it shows how
there is support by other subsystems that helps the Profile subsystem to
accomplish the goals of managing the profiles within ArgoUML.
Section 5.7.3, “Defining profiles” –
describes what means the subsystem provides that enable profiles to be defined
by modules and by users.
Section 5.7.4, “History of the Profile subsystem” –
provides a small history on the subsystem and some links to issues that might
be interesting to someone that wants to get involved in the Profile subsystem
maintenance and evolution.
5.7.1. Initialization of the profile subsystem
To initialize the profile subsystem you do:
new org.argouml.profile.init.InitProfileSubsystem().init();
This will create a new instance of the class that implements the
ProfileManager interface and set
ProfileFacade to use this instance of
ProfileManager...
Which, by the way is currently ProfileManagerImpl,
from the org.argouml.profile.internal package.
Check Figure 5.6, “Sequence diagram of the profile subsystem initialization.” for more details.
To complete the description we explain how to re-initialize the subsystem:
new org.argouml.profile.init.InitProfileSubsystem().init();
Simple enough?!
But, what does it mean from an internal point of view?
Well, the prior internal objects that were used by the subsystem are left alone
and hopefully the garbage collector will clean the memory they occupy.
So, it simply creates new fresh objects and these are attached to
ProfileFacade.
This is of use in the automated tests, where there is the need to guarantee
that the status of the subsystem isn't changed by previously executed test
fixtures.
5.7.2. Profile(s) management
For a profile to be known by the profile subsystem it must be registered.
This is done by external entities, like for instance, a language module to
register its UML profile would do:
ProfileFacade.register(profile);
Which is a synonym for:
ProfileFacade.getManager().registerProfile(profile);
Another possibility is for the profile manager to register its own profiles.
That happens for the UML profile, being created by the profile manager and
then registered by it.
That also happens for user defined profiles, which consist of XMI files that
the user places in some directories and afterwards, using the GUI, marks the
directories as containing user defined profiles.
All of these registered profiles have the common base class
Profile, which establishes the interface that must be
implemented by a profile so that it is registrable.
The Figure 5.7, “Class diagram of the Profile class and
some derived classes”
shows the Profile class and its specialized classes
ProfileUML and UserDefinedProfile.
ProfileUML is the class that specializes
Profile with behavior specific for the UML profile;
UserDefinedProfile is a specialization that contains
functionality for loading and representing a user defined profile.
As it is possible to register a Profile in the
ProfileManager, it is possible to unregister it also.
A common case is that of a ArgoUML language module, which registers its
specific Profile when enabled and unregisters it when
it is disabled.
Figure 5.8, “Sequence diagram of the registering and unregistering of a
profile”
illustrates this, standing the module
ClassifierRole as a language module which is activated by
moduleManager by a call to its operation enable.
As part of the activation, module creates the
moduleProfile and registers it in the profile subsystem by a
call to the register(moduleProfile) operation of the
ProfileFacade.
The deactivation of the module causes the call to the
remove(moduleProfile), which will unregister the
moduleProfile in the profile subsystem.
After a profile is registered, it may be chosen as a default profile by the
user.
A default profile is a profile which is added to new projects by default.
For this there is the class org.argouml.ui.SettingsTabProfile
that is part of the ArgoUML application settings dialog and shows
all the registered profiles, being the profiles set as default profiles shown
in a specific list.
The ProfileManager is responsible for keeping track of
the profiles chosen as default.
For this, it has the operations:
List<Profile> getDefaultProfiles()
void addToDefaultProfiles(Profile profile)
and
void removeFromDefaultProfiles(Profile profile)
Besides the class org.argouml.ui.SettingsTabProfile for
handling application wide settings of the profile subsystem, there is the class
org.argouml.ui.ProjectSettingsTabProfile to enable the
users to modify the profile subsystem project settings, which take the form of
an instance of the class
org.argouml.kernel.ProfileConfiguration.
The class org.argouml.ui.ProjectSettingsTabProfile also
shows all the registered profiles, as
org.argouml.ui.SettingsTabProfile does, but, this time
it is to enable the user to add or remove profiles to an open project.
In its operation handleSettingsTabSave() the changes the
user did are made in the instance of
org.argouml.kernel.ProfileConfiguration.
The ProfileConfiguration is a
ProjectMember and is part of a
Project.
It is persisted and loaded to/from a project file by means of an instance of
the class org.argouml.persistence.ProfileConfigurationFilePersister.
These two classes aren't part of the profile subsystem, but, are closely
related.
Specifically, the ProfileConfiguration is part of the
kernel subsystem and the ProfileConfigurationFilePersister
is part of the persistence subsystem.
It all starts with a XMI file containing a model...
User defined profiles are simply this, at least from the point of view of the
author of the profile.
So, to define a profile you start by modeling the profile in an ArgoUML project
and then export it as XMI.
The profile subsystem provides means to add additional features to the
profiles, but, for this you must get your hands dirty with a bit of java coding.
Recall the Profile class in
Figure 5.7, “Class diagram of the Profile class and
some derived classes”.
The additional things that may be added to an ArgoUML profile, but, which
require coding are:
a FormatingStrategy, which provides specific formatting
services to profile model elements;
a FigNodeStrategy, which provides figures to be shown
instead of the textual representation of the profile stereotypes;
a DefaultTypeStrategy, which defines default types for
attributes, parameters and return values appropriate for the profile.
Unfortunately these extras are only possible for profiles contained in
extension modules, such as the UML profile for C++, or profiles contained
within ArgoUML, such as the UML profile of UML.
This limitation is caused by the need to load the Java classes that would
implement the extended behavior.
![[Note]](images/note.png) | Note |
|---|
If the work in progress by Marcos Aurélio is successful and is integrated
into ArgoUML it is possible that the above customizations are performed without
any Java coding.
This could make user defined profiles and module contained profiles virtually
equivalent in what concerns the functionality provided.
For more information see
issue
#5029: Improve Plugability of Profile Subsystem.
|
There is a detail that must be taken into account when defining profiles which
is the ProfileReference that must be associated to each
profile.
See Figure 5.9, “Class diagram of the ProfileReference class
and associated classes” for a diagram that shows how
these classes are associated with Profile and
ProfileModelLoader derived classes.
When a profile model is loaded, it must be associated with a
ProfileReference instance which defines for the profile
a path and a public reference (a URL).
The path part of a profile reference is something that enables ArgoUML to
locate and load the actual XMI file.
The public reference is something that will identify the profile uni-vocally,
enabling references to model elements of profiles from other models.
Specifically it is very important to guarantee that the persisted models that
refer to profiles are correctly loaded in other ArgoUML installations than the
ones that originally created the models.
5.7.4. History of the Profile subsystem
The profile subsystem was the result of the
Google
Summer of Code project of Marcos Aurélio in 2007.
Much of the design of
Marcos'
original purposal is still present in the subsystem.
His GSoC mentor was Linus Tolke and the work was integrated into ArgoUML trunk
by Tom Morris during September of 2007.
Previously Tom Morris was involved in adding support for cross XMI file
references, which are required for the profiles to work.
After the bulk of the work in creating and integrating the subsystem, we list
some issues that might be of interest to persons that want to go after
the reasoning behind some of the decisions that took the subsystem to where it
is now or which should be solved to raise the subsystem to a quality level above
average:
Follow some of the issues that might affect the future of the subsystem: