Customization and platform development
Introduction
The core of Objecteering
C++ Developer is an Active Code Template (ACT) processor. An ACT is an open XML-based description of
code to be generated, which groups together:
·
Instructions
describing the layout and structure of code
·
ACT structuring
and translation flow instructions
·
Rules for
the extraction of code from UML models, expressed through MDA profile methods
and J code
·
Custom MDA
profile method calls and custom J code
·
Mappings
associating ACTs and arbitrary text strings with text keys
ACTs are linked to
model elements and output files by generation products. A generation product is
an open XML-based description, which links a UML metaclass, a condition
defining when elements of this metaclass are translated, an ACT defining how
these elements are translated, and the name of an output file containing the
translated code.
ACT syntax
provides various convenient features, including the following:
·
Structuring
of ACTs through macro substitution and inclusion
·
Separation
of presentation and logic
·
Conditional
and iterative generation
·
ACT
overriding
·
Execution
of custom MDA profile methods and J code during generation
Due to the structuring
of ACTs, generation products are defined only for top-level UML model elements
(packages and classes).
ACTs can be
grouped into the following categories:
·
Type
libraries
·
Template
libraries
·
Pattern
libraries
·
Compilation
definitions
A type library
groups together definitions of types. A type definition associates a UML type
with an ACT describing the representation of the type in C++. This ACT usually defines a C++ declaration,
where the name of a UML structural feature or operation parameter will be
substituted, and a list of include directives required to use the C++ type.
A UML type can be
a primitive type, a data type or a collection type. Collection types are used
to represent attributes and association ends with multiple cardinalities. The
definition of a collection type also provides a high-level description of
collection semantics – such as "OrderedCollection" – which is mapped
to decorations automatically deduced from high-level UML model properties. This
allows Objecteering C++ Developer to automatically express high-level UML model
semantics through particular C++ collection types.
In addition, a
type library can provide custom ACTs, which describe code or even UML model
features required to use the library, for example, injection of macro
definitions, initialization of allocators, creation of model-level factories,
and so on.
Objecteering C++
Developer can simultaneously support a number of type libraries. You can
specify a type library arbitrarily– from MDA component properties or a build
project through packages and classes to particular attributes or operation
parameters.
When Objecteering
C++ Developer translates a structural feature or an operation parameter, it
constructs the C++ declaration in accordance with its type and the current type
library, and executes ACTs defined in the library, if they override the core
ACTs defined for the element.
You can create your
own type libraries by writing custom type definitions and ACTs. Objecteering
C++ Developer automatically uploads these type libraries, so new type libraries
can be immediately tested and applied.
A template
library groups together ACTs defining the translation of certain model elements
and their contents.
You can define your
own template libraries by writing custom ACTs and overriding the core ACTs
defined for UML model elements or their contents. Non-overridden ACTs can be
transparently re-used.
This possibility
of creating template libraries means that you can re-define the layout and
structure of generated code and define custom generation actions. Since ACTs are used to express calls to MDA
profile methods and J code, you can define calls to your own MDA methods and define
your own J code. These methods and this code will be automatically executed by Objecteering
C++ Developer during translation of UML model elements, in accordance with
selected ACTs, meaning that it is possible to define custom naming conventions,
run consistency checks (generation of error messages if certain conditions are
not satisfied), compute and generate custom metrics, and so on.
Generation
products are used to define custom output files for UML model elements.
You can define your
own generation product by associating:
·
a UML
metaclass
·
a
generation condition expressed by a J expression or an MDA profile method call
·
a rule to
generate the output file name
·
a custom
ACT defining the output.
This means that
you can define custom output, in addition to generated C++ code (IDL
definitions or Java Native Interface wrappers, documentation in custom format,
and so on).
Objecteering C++
Developer can simultaneously support a number of generation product
definitions.
A pattern
library groups together pattern definitions. A pattern associates a UML
metaclass, a kind of pattern and a set of ACTs describing the transformation of
the UML model when the pattern is applied to the elements of this metaclass. Since ACTs make it possible to express calls
to MDA profile methods and J code, model transformation rules can be defined directly
in the language best suited to the description of model transformations.
A pattern can be
dynamic, meaning that the pattern definition associates standard events with
ACTs describing the transformation of the UML model following an event (the
creation or renaming of model elements, and so on). Objecteering triggers events
when the UML model is changed, so Objecteering C++ Developer automatically
executes associated ACTs, inducing respective model transformations.
Model-level
accessors and creation operators are examples of dynamic patterns.
Objecteering C++
Developer can simultaneously support a number of pattern libraries. The pattern
metaclass and attribute kinds are used to let you conveniently select the
desired pattern through the dedicated GUI.
You can create your
own template libraries by writing custom model transformation ACTs (Active
Model Templates). Objecteering C++ Developer automatically uploads these
template libraries, so new patterns can be immediately tested and applied.
A compiler
definition groups together type definitions, ACTs and specifier mappings, which
express the specifics of a particular compiler.
Type definitions
describe specific types natively supported by the compiler. Specifier mappings
describe how C++ type specifiers such as "cdecl" or
"dllexport" are represented by the C++ constructions in the compiler.
ACTs describe code generation rules according to compiler specifics (generation
of inline template functions or export templates, and so on).
When Objecteering
C++ Developer translates a UML model element, it constructs its C++ declaration
according to the mapping of its specifiers and the ACTs defined for the current
compiler. This makes it possible to transparently generate portable code,
without being distracted by the specifics of a particular compiler and without resorting
to ugly conditional macro magic.
Objecteering C++
Developer can simultaneously support a number of compiler definitions. You can
specify a compilation platform for the whole MDA component or for particular
build projects, meaning that you can easily support compilation for several
compiler targets, which can be quite practical when libraries are being developed.
You can also create
your own compiler definitions by writing custom types, ACTs and specifier
mappings. Objecteering C++ Developer automatically uploads these, so new
compiler definitions can be immediately tested and applied.