Model Driven Architecture For Reverse Engineering Technologies Strategic Directions and System Evolution
Model Driven Architecture For Reverse Engineering Technologies Strategic Directions and System Evolution
Table of Contents
Preface ................................................................................................................................................viii
Acknowledgment ................................................................................................................................ xiv
Section 1
Basics
Chapter 1
Reverse Engineering and MDA: An Introduction .................................................................................. 1
Introduction ............................................................................................................................................. 1
Reverse Engineering in the Last 20 Years .............................................................................................. 4
Reverse Engineering and MDA............................................................................................................... 6
References ............................................................................................................................................. 13
Chapter 2
Model Driven Architecture (MDA) ...................................................................................................... 15
Introduction ........................................................................................................................................... 15
The Basic Concepts ............................................................................................................................... 17
UML Metamodel ................................................................................................................................... 20
The Meta Object Facility (MOF) .......................................................................................................... 25
Four-Layer Architecture ....................................................................................................................... 27
Profiles vs. Metamodels ........................................................................................................................ 30
References ............................................................................................................................................. 31
Chapter 3
MDA, Metamodeling and Transformation ........................................................................................... 34
Introduction ........................................................................................................................................... 34
MOF Constructs.................................................................................................................................... 35
Examples ............................................................................................................................................... 37
Common Concepts on Transformations ................................................................................................ 45
References ............................................................................................................................................. 47
Section 2
Formalization of MOF-Based Processes
Chapter 4
Formalization of MOF-Based Metamodels .......................................................................................... 49
Introduction ........................................................................................................................................... 49
Object-Orientation, Metamodeling and Formal Languages ................................................................ 50
MDA Infrastructure............................................................................................................................... 52
NEREUS: A Metamodeling Language .................................................................................................. 54
Example 4-1: OCL Collections in NEREUS ......................................................................................... 60
Example 4-2: Bidirectional Associations in NEREUS .......................................................................... 67
Example 4-3: Aggregation/Composition in NEREUS........................................................................... 69
Example 4-4: State Diagram Metamodel ............................................................................................. 71
Example 4-5: QVT Core Formalization................................................................................................ 73
References ............................................................................................................................................. 76
Chapter 5
MOF-Metamodels and Formal Languages ........................................................................................... 80
A Bridge Between MOF-Metamodels and NEREUS ............................................................................ 80
Transformation of Associations ............................................................................................................ 83
Transformation of OCL Specification into NEREUS ............................................................................ 83
Example 5-1: Class Diagram Specified in OCL ................................................................................... 85
References ............................................................................................................................................. 97
Chapter 6
Mappings of MOF Metamodels and Algebraic Languages .................................................................. 98
Introduction ........................................................................................................................................... 98
Translating Basic Specifications ........................................................................................................... 99
Translating Associations ..................................................................................................................... 102
Example 6-1: Translating P&M Class Diagram into CASL............................................................... 102
References ........................................................................................................................................... 106
Chapter 7
Mappings of MOF Metamodels and Object-Oriented Languages ...................................................... 107
Introduction ......................................................................................................................................... 107
Mapping Classes and Associations ..................................................................................................... 107
Constructing Object-Oriented Contracts and Implementations ......................................................... 111
References ........................................................................................................................................... 112
Section 3
Techniques Underlying MDA-Based Reverse Engineering
Chapter 8
Software Evolution, MDA and Design Pattern Components.............................................................. 115
Introduction ......................................................................................................................................... 115
Related Work ....................................................................................................................................... 116
A Megamodel for Defining MDA Reusable Components.................................................................... 117
Specifying MDA Design Pattern Components .................................................................................... 119
The Observer Component ................................................................................................................... 120
PIM-Metamodel of the Observer Pattern ........................................................................................... 121
PSM-Metamodel of the Observer Pattern........................................................................................... 136
ISM-Metamodel of the Observer Pattern ............................................................................................ 140
Specifying Metamodel-Based Transformations .................................................................................. 143
Formalization of Megamodel Instances.............................................................................................. 150
References ........................................................................................................................................... 156
Chapter 9
Evolution of Models and MDA-Based Refactoring ........................................................................... 158
Introduction ......................................................................................................................................... 158
Related Work ....................................................................................................................................... 159
MDA-Based Refactoring ..................................................................................................................... 160
Specifying MDA Refactoring .............................................................................................................. 161
Refactoring at Metamodel Level ......................................................................................................... 161
Refactoring at Model Level................................................................................................................. 182
Refactoring at Formal Language Level .............................................................................................. 185
Example 9-1: State Machine Diagram Refactoring............................................................................ 190
References ........................................................................................................................................... 196
Chapter 10
MDA-Based Object-Oriented Reverse Engineering ........................................................................... 199
Introduction ......................................................................................................................................... 199
Related Work ....................................................................................................................................... 200
CASE Tools ......................................................................................................................................... 201
A Framework for Reverse Engineering .............................................................................................. 204
Code-to-Model Transformations......................................................................................................... 206
Code-to-Model Transformations: The Bases for Recovering Class Diagram .................................... 214
Code-to-Model Transformations: The Bases for Recovering State Diagram..................................... 215
MOF-Based Formalization: Reverse Engineering UML Class Diagram .......................................... 218
MOF-Based Formalization: Reverse Engineering UML State Diagram ........................................... 221
Specifying Anti-Refinements in NEREUS............................................................................................ 224
References ........................................................................................................................................... 226
Section 4
Conclusions
Chapter 11
Summing Up the Parts ........................................................................................................................ 231
Reverse Engineering: A Different Point of View ......................................................................... 231
Challenges on MDA-Based Reverse Engineering ...................................................................... 234
Chapter 12
Towards MDA Software Evolution .................................................................................................... 236
Introduction ................................................................................................................................. 236
Challenges on MDA-Based Software Evolution ......................................................................... 237
References ................................................................................................................................... 239
Section 5
Selected Readings
Chapter 13
Foundations for MDA Case Tools ...................................................................................................... 242
Liliana Favre, Universidad Nacional del Centro de la Pcia. de Buenos Aires, Argentina
Claudia Teresa Pereira, Universidad Nacional del Centro de la Pcia. de Buenos Aires, Argentina
Liliana Ins Martinez, Universidad Nacional del Centro de la Pcia. de Buenos Aires, Argentina
Chapter 14
A Rigorous Framework for Model-Driven Development ................................................................... 253
Liliana Favre, Universidad Nacional del Centro de la Provincia de Buenos Aires, Argentina
Section 6
Appendices
Appendix A
Platform Specific Metamodels and Language Metamodels................................................................ 278
A.1. PSM Metamodel: Eiffel Platform ................................................................................................ 278
A.2. PSM Metamodel: Java Platform ................................................................................................. 284
A.3. ISM Metamodel: Eiffel Language ............................................................................................... 294
A.4. ISM Metamodel: Java Language................................................................................................. 305
A.5. ISM Metamodel: C++ Language ................................................................................................ 316
Appendix B
OCL and NEREUS: Type System....................................................................................................... 332
B.1. Primitive Types ............................................................................................................................ 332
B.2. Collection Types .......................................................................................................................... 348
B.3. Enumeration Signature ................................................................................................................ 355
B.4. Type Constructors ........................................................................................................................ 355
Appendix C
Transformation Rule System .............................................................................................................. 381
The Object Constraint Language: An Overview ................................................................................. 381
From OCL to NEREUS: A System of Transformation Rules .............................................................. 386
Appendix D
Design Pattern Metamodels ................................................................................................................ 396
D.1. EiffelPSM Observer Metamodel ............................................................................................... 396
D.2. JavaPSM Observer Metamodel ................................................................................................ 406
D.3. JavaISM Observer Metamodel.................................................................................................. 420
About the Author .............................................................................................................................. 437
Index ................................................................................................................................................... 438
viii
Preface
The software industry has evolved to tackle new approaches aligned with the Internet, object-orientation,
distributed components and new platforms. However, the majority of the large information systems
running today in many organizations were developed many years ago with technologies that are now
obsolete. These old systems, known as legacy systems, include software, hardware, business processes
and organizational strategies and policies. Many are still business-critical and their complete replacement
is dangerous and their maintenance is increasingly expensive. The amount of code in legacy systems is
immense; there are billions upon billions of lines of code in existence that must be maintained.
The demand for modernization of legacy systems created the need for new architectural frameworks
for information integration and tool interoperation that allow managing new platform technologies,
design techniques and processes. The Object Management Group (OMG) adopted the Model Driven
Architecture (MDA) that is an evolving conceptual architecture aligned with this demand.
Beyond interoperability reasons, there are other benefits to using MDA such as improving productivity, process quality and maintenance costs. MDA itself is not a technology specification, but it represents
an evolving plan to achieve cohesive model-driven technology specifications.
All artifacts, such as requirement specifications, architecture descriptions, design descriptions and
code are regarded as models. MDA distinguishes at least the following ones:
Computation Independent Model (CIM): a model that describes a system from the computation
independent viewpoint that focuses on the environment of and the requirements for the system. In
general, it is called domain model.
Platform Independent Model (PIM): a model with a high level of abstraction that is independent
of any implementation technology.
Platform Specific Model (PSM): a tailored model to specify the system in terms of the implementation constructs available in one specific platform.
Implementation Specific Model (ISM): a description (specification) of the system in source
code.
The idea behind MDA is to manage the evolution from CIMs to PIMs and PSMs that can be used to
generate executable components and applications. In MDA, it is crucial to define, manage, and maintain
traces and relationships between different models and automatically transform them and produce code
that is complete and executable.
We can distinguish three main transformations in MDA processes: refinements, anti-refinements
and refactorings. A refinement is the process of building a more detailed specification that conforms to
another that is more abstract. On the other hand, an anti-refinement is the process of extracting from
a more detailed specification (or code) another, more abstract specification that is conformed by the
ix
more detailed specification. Refactoring means changing a model, leaving its behavior unchanged, but
enhancing some non-functionality quality factors such as simplicity, flexibility, understandability and
performance.
The initial diffusion of MDA was focused on its relation with the Unified Modeling Language (UML)
as modeling language. However, there are UML users who do not use MDA, and MDA users who use
other modeling languages such as Domain Specific Languages (DSLs).
MDA requires the ability to understand different languages such as general purpose languages, domain
specific languages, modeling languages or programming languages. An underlying concept of MDA for
integrating such languages semantically in a unified and interoperable way is metamodeling.
The essence of MDA is the Meta-Object-Facility (MOF) metamodel that allows different kinds of
artifacts from multiple vendors to be used together in the same project.
MOF (latest revision 2.0) defines a common way to capture all the diversity of modeling standards
and interchange constructs. It provides a metadata management framework where models can be, for
instance, exported from one application, imported into another, stored in a repository and then retrieved,
transformed, and used to generate code. The MOF 2.0 Query, View, Transformation (QVT) metamodel
addresses queries on models, views on metamodels and transformations of models.
With the emergence of MDA, new approaches should be developed in order to reverse engineering,
both platform independent and platform specific models, from object oriented code.
This book is a contribution for the demand of system modernization. In particular, the objective of
this book is to analyze the integration of MDA with reverse engineering techniques to control the evolution of systems towards object oriented technologies.
A central problem is how to correctly define metamodels and align them with MOF. Inconsistencies in a metamodel specification will affect models and their implementations. MOF-metamodels are
expressed as a combination of UML, the Object Constraint Language (OCL) and natural language.
MOF has no built-in semantics apart from the well-formedness rules in OCL and what can deduced
from them. This form of specification does not make it possible to validate that specific metamodels
like UML metamodel conform to MOF (in the sense of each metaclass of the metamodel conforms a
MOF meta-metaclass). A combination of MOF metamodeling and formal specification can help us to
address MDA. A formal specification allows us to produce a precise and analyzable software specification and clarifies the intended meaning of metamodels. It also helps to validate model transformations,
and provides reference for implementations.
In light of this, the book proposes an integration of classical compiler techniques, metamodeling
techniques and algebraic specification techniques to make a significant impact on the automation of
MDA-based reverse engineering processes.
The proposed approach has two main advantages linked to automation and interoperability. On the one
hand, our approach shows how to automatically generate formal specifications from MOF metamodels.
Due to scalability problems, this is an essential requisite. On the other hand, it focuses on interoperability of formal languages.
Reverse engineering and software evolution are crucial and complex research domains in software
engineering. This book intends to increase the consciousness of the advantages of defining MDA-based
reverse engineering and software evolution processes. It emphasizes techniques that are the foundations
of innovative MDA processes and inspires research to open new frontiers with the power of MDA Case
tools.
To date, most model-driven development research emphasizes on Software Language Engineering.
Perhaps in the coming years, the focus will be on Software Engineering Processes. This book intends
to shorten the path to this goal by providing an overview of several techniques that can be adopted in
MDA-based processes.
This book was written for a broad audience of researchers, advanced students, professionals and those
people that have adopted reverse engineering practices or are about to invest in system modernization. It
encourages software professionals to explore the use of MDA for innovative projects that involve reverse
engineering efforts combined with software evolution. It can also be used in advanced undergraduate
courses to teach reverse engineering as an integral part of software design processes.
We assume that readers have a general knowledge of object oriented modeling, in particular UML
models. A self-contained discussion of the principles of reverse engineering in a novel context including
topics such as MDA, OCL, MOF, UML metamodel and QVT is presented.
Section 1: Basics
Section 2 : Formalization of MDA Processes
Section 3: Techniques Underlying MDA-Based Reverse Engineering
Section 4: Conclusions
Section 5: Selected Readings
Section 6: Appendices
Section 1 includes a discussion of the fundamentals of reverse engineering and MDA. It also includes
a description of the main OMG standards involved in MDA processes. It introduces the main concepts
of MOF-based metamodeling techniques for specifying platforms, models and metamodel-based transformations. It includes three chapters:
Section 2 describes foundations for metamodeling. It shows how to specify a metamodel by using
formal specifications and how to generate formal specifications in an automatic way. Also, this section
show how different formalization styles can be integrated. It includes four chapters:
Section 3 is a central part of this book. It describes underlying techniques in MDA processes, in particular in reverse engineering and software evolution. It describes how to adapt crucial techniques such
as design patterns, model refactoring and pattern recovery in a way that fits with MDA. It includes the
description of a framework for reverse engineering object oriented code. It includes three chapters:
xi
Section 4 summarizes the main contributions and includes strategic directions and challenges in MDA
reverse engineering and software evolution. It includes two chapters:
Finally, the book also includes appendixes and selected readings that provide complementary information about metamodels, platforms, languages and formalisms.
Next, we describe contents of the different sections.
Section 1: Basics
Chapter 1: Reverse Engineering and MDA: An Introduction
This chapter gives an overview of state-of-the-practices in reverse engineering techniques and motivates
the interest that Model Driven Reverse Engineering has gained in different application areas related to
the evolution of existing software.
xii
rules for translating OCL specifications into NEREUS. The chapter exemplifies the different steps of
the transformation process.
xiii
Section 4: conclusions
Chapter 11: Summing Up the Parts
This chapter summarizes the main results described in the book and challenges in MDA reverse engineering.
xiv
Acknowledgment
I am very grateful to all the staff at IGI Global, whose contributions throughout the whole process from
the inception of the initial idea to final publication have been invaluable. I would also like to thank all
members of the publishing team at IGI Global. I am very grateful to Julia Mosemann for a huge amount
of help in preparing this book. I gratefully acknowledge the useful comments and suggestions made
by the anonymous reviewers whose feedback helped me improve the book. In closing, I would like to
express my gratitude to Mehdi Khosrow-Pour at IGI Global.
Liliana Favre
Universidad Nacional del Centro de la Provincia de Buenos Aires
Comisin de Investigaciones Cientficas de la Provincia de Buenos Aires
Argentina
Section 1
Basics
Chapter 1
intrOductiOn
Reverse Engineering is the process of analyzing available software artifacts such as requirements, design,
architectures, code or byte code, with the objective of extracting information and providing high-level
views on the underlying system.
A common idea in reverse engineering is to exploit the source code as the most reliable description
both of the behavior of a software system and of the organization and its business rules. However, reverse
engineering is immersed in a variety of tasks related to comprehending and modifying software such
as re-documentation of programs and relational databases, recovering of architectures, recovering of
alternative design views, recovering of design patterns, building traceability between code and designs,
modernization of interfaces or extracting the source code or high level abstractions from byte code when
the source code is not available.
Reverse engineering is hardly associated with modernization of legacy systems that were developed
many years ago with technology that is now obsolete. These systems include software, hardware, business processes and organizational strategies and politics. Many of them remain in use after more than 20
years; they may be written for technology which is expensive to maintain and which may not be aligned
with current organizational politics. Legacy systems resume key knowledge acquired over the life of an
organization. Changes are motivated for multiple reasons, for instance the way in which we do business
and create value. Important business rules are embedded in the software and may not be documented
elsewhere. The way in which the legacy system operates is not explicit (Brodie and Stonebraker, 1995)
(Sommerville, 2004).
On the one hand, there are billions upon billions of lines of legacy code in existence, which must
be maintained with a high cost and, on the other hand, there is a high risk in replacing legacy systems
DOI: 10.4018/978-1-61520-649-0.ch001
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
that are still business-critical. The cost of reengineering should be significantly less than the cost of a
new developing.
Reverse engineering does not involve changing the source legacy systems, but understanding them
to help reengineering processes that are concerned with their re-implementing. Software reengineering
starts from an existing implementation and requires an evaluation of every part of the system that could
be transformed or implemented anew from scratch. This definition distinguishes the following main
phases:
the examination and the alteration of a subject system to reconstitute it in a new form
and
the subsequent implementation in a new form. (Demeyer, Ducasse and Nierstrasz, 2002)
In other words, reengineering includes some form of reverse engineering followed by some form
of forward engineering. Reverse engineering is the process of examination, not the process of change.
Chikofsky and Cross (1990) define reverse engineering and forward engineering:
Reverse engineering: the process of analyzing a subject system to (i) identify the systems components and their interrelationships and (ii) create representations of the system in another form
or at a higher level of abstraction
Forward engineering: the traditional process of moving from high-level abstractions and logical, implementation-independent designs to the physical implementation of a system
Reverse engineering and related processes are using only three life-cycle phases: requirements specifications (including objectives, constraints and business rules), design of the solution and implementation
(coding, testing, and delivery of the operational system) (Chikofsky & Cross, 1990).
Figure 1 depicts the relationship between tasks related to reverse engineering expressing transformations between or within abstraction levels linked to lifecycle phases. It also shows three processes related
to reverse engineering: re-documentation, design recovery and restructuring.
Re-documentation is the creation of a representation of software artifacts that existed or should have
existed within the same relative abstraction level. The resulting forms of representation are usually
considered alternate views (for example dataflow, Abstract Syntax Tree, Patterns).
Design recovery rebuilds design abstractions from an integration of code, existing design documentation
(if available), personal experience, and general knowledge about problem and application domains.
Restructuring is the transformation of a software artifact from one representation form to another at
the same relative abstraction level, while preserving the artifact external behavior.
Reverse engineering has been used with two essential goals: design recovering and abstraction;
however, it can be used to obtain more abstract representations with other purposes, for example testing,
quality assurance, reuse and security.
Reverse engineering has been related with software evolution and maintenance. Software evolution
is the process of initial development of a software artifact, followed by its maintenance. The ANSI/
IEEE standard 729-1983 (Ansi/IEEE, 1884) defines software maintenance as the modification of a
software product after delivery to correct faults, to improve performance or other attributes, or to adapt
the product to a changed environment. This definition focuses on modification after delivery however
maintenance lasts a long time than the initial development. This definition does not cover implementation of new functionality and it is not aligned with modern developments that require characterizing the
implementation of changes in response to change request with reference to the whole life cycle.
Reverse engineering techniques can be used as a mean to design software systems by evolving existing
ones based on new requirements or technologies. It involves extracting higher-level design abstractions
from an existing operational system, but this is not a requirement. On the one hand, it can start from any
level of abstraction or at any stage of the life cycle. On the other hand a system must be continuously
reverse engineered during its life cycle and integrated with the evolution of software artifacts. Changes
can be related to correcting software (corrective maintenance), adapting a system to a new environment
(adaptive maintenance) or implementing new functional or non-functional requirements (perfective
maintenance) (IEEE, 1984).
Baxter and Mehlich (1997) argue that reverse engineering needs the same knowledge and infrastructure as forward engineering. When the reverse engineering and forward engineering are placed
within the contexts of building new systems in a more incremental and evolutionary style of development the resulting process is round-trip engineering. The goal of round-trip engineering is to provide
the generation of models from source code and generation of source code from models, while it keep
the two views consistent.
In particular, reengineering includes a reverse engineering phase in which an abstraction of the software artifacts to be reengineered is built, and a forward engineering phase. A reengineering process can
be view as a conceptual horseshoe model that distinguishes different levels of analysis and provides
foundations for logical transformations at different abstraction levels, especially for transformations to
the architectural level and the development of a new system (SEI, 2009). These three processes form
the basis of the horseshoe as illustrated in Figure 2.
When the object oriented languages emerged, a growing demand for reengineering object oriented
systems appeared on the stage. New approaches were developed to identify objects into legacy code
(e.g. legacy code in COBOL) and translate this code into an object oriented language. Many objectoriented languages allow for high dynamicity loading classes at run-time and supporting the concept of
reflection. The first results showed shortcomings about comprehensibility and maintainability of object
oriented target code, for instance, design of classes and interrelations do not adhere to the object-oriented
philosophy.
The compiler techniques were adapted to perform a propagation of proper data in a graph representation of the object flows occurring in an execution (Aho, Sethi and Ullman, 1985). In this context, the
data flow is called the Object Flow Graph (Tonella & Potrich, 2005). It allows tracking the lifetime of
the objects from their creation along their life-cycle.
Object-oriented programs are essentially dynamic and present particular problems linked to polymorphism and late binding, abstract classes and dynamically typed languages. For example, some object
oriented languages introduce concepts such as the reflection and the possibility of loading dynamically
classes, although these are powerful mechanisms, they affect reverse engineering techniques. The object
oriented features such as method redefinition, dynamic method resolution and dynamic associations
between classes require capturing system states through dynamic analysis.
Then, during the time of object-oriented programming the focus of software analysis moved from
static analysis to dynamic one, more precisely static analysis was complemented with dynamic one.
Correspondingly, reverse engineering techniques had to be customized to address these aspects.
At time of object orientation, a new generation of tracer tools assisting in dynamic analysis appeared
on the marketplace. The term refactoring was introduced by Martin Fowler for defining a special kind
of restructuring in object-oriented code (Fowler, 1999):
Refactoring is the process of changing a software system in such a way that it does not alter the external
behavior of the code yet improves its internal structure (Fowler, 1999).
Object-oriented development was accompanied by the use of design patterns (Gamma et al., 1990)
and anti-patterns (Laplante and Neill, 2005) that can be identified by static and dynamic analysis promoting reuse and software quality.
When the Unified Modeling Language (UML) (OMG, 2009-a) (Booch, Rumbaugh and Jacobson,
2005) comes into the world, a new problem was how to extract higher level views of the system expressed
by different kind of UML diagrams.
The diagrams that could be reverse-engineered in this way were partial. A new challenge was how to
identify different relationships (e.g. dependency, association, aggregation and composition). While there
exists relevant work for extracting UML diagrams (e.g. class diagram, state diagram, sequence diagram,
object diagram, activity diagram and package diagram) from source code, a lot of challenges still needs
to be done, for instance it is an open problem the extraction of dynamic diagrams and the integration of
specification in the Object Constraint Language (OCL) (OCL, 2006). Software environments provide
a wide variety of tools to handle the reverse engineering at different dimensions. Although, there are
tools for slicing, refactoring, design patterns and test cases, in general they are not integrated with one
other in order that software evolves consistently.
Computation Independent Model (CIM): a model that describes a system from the computation independent viewpoint that focuses on the environment of and the requirements for the system. In general it is called domain model.
Platform Independent Model (PIM): a model with a high level of abstraction that is independent of any implementation technology.
Platform Specific Model (PSM): a tailored model to specify the system in terms of the implementation constructs available in one specific platform.
Implementation Specific Model (ISM): a description (specification) of the system in source
code.
MDA is carried out as a sequence of model transformations. We can distinguish three main transformations: refinements, anti-refinements and refactorings. A refinement is the process of building a
more detailed specification that conforms to another that is more abstract. On the other hand, an antirefinement is the process of extracting from a more detailed specification (or code) another one, more
abstract, that is conformed by the more detailed one. Refactoring means changing a model leaving its
behavior unchanged, but enhancing some non-functionality quality factors such as simplicity, flexibility,
understandability and performance.
One of the main issues behind MDA is that all artifacts generated during software development are
represented using common metamodeling languages. Metamodels integrate semantically different languages, platforms and technologies in a unified way. Figure 4 shows interrelationships between models,
metamodels and transformations.
MDA is associated with popular OMG standards: the modeling language UML, the metamodel MOF
(Meta Object Facility), the standard for defining metamodels and, the Query, View, Transformation
Metamodel (QVT), the standard to express transformations (MOF, 2006) (QVT, 2008).
UML is a language for specifying, visualizing, constructing and documenting software intensive
systems. It is a unifier of proven software modeling languages that incorporates the object-oriented
communitys consensus on core modeling concepts and includes additional expressiveness to handle
problems that previous languages did not fully address. UML has evolved as a result of insights gained
through their use to the current version UML 2.2. It consists of two parts: Infrastructure and Superstructure
that are associated with the Object Constraint Language (OCL) and Diagram Interchange specifications
(UML, 2009-a) (UML, 2009-b) (OCL, 2006).
The initial diffusion of MDA was focused on its relation with UML as modeling language. However,
there are UML users who do not use MDA, and MDA users who use other modeling languages such
as Domain Specific Languages (DSL) (Mernik, Heering & Sloane, 2005) (Krahn, Rumpe, & Volkel,
2008).
The essence of MDA is MOF that allows different kinds of software artifacts to be used together in
a single project. MOF defines a common way for capturing all the diversity of modeling standards and
interchange constructs.
MOF uses an object modeling framework that is essentially a subset of the UML core. The 4 main
modeling concepts are classes, associations, which model binary relationships, Data Types, which model
other data, and Packages which modularize the models.
QVT standard depends on MOF and OCL for specifying queries, views, and transformations. A query
selects specific elements of a model, a view is a model derived from other model and, a transformation
is a specification of a mechanism to convert the elements of a model, into elements of another model.
A PIM-metamodel is related to more than one PSM-metamodels, each one suited for different platforms, e.g. .NET, J2EE or relational. The PSM-metamodel corresponds to ISM-metamodels. A metamodel
is a description of all the concepts that can be used in the respective level. For instance, a metamodel
linked to a relational platform refers to concepts of table, foreign key and column. An ISM-metamodel
includes concepts of programming languages such as constructor and method.
Metamodel transformations are a specific type of model transformations that impose relations between
pairs of metamodels. A metamodel-based transformation is a specification of a mechanism to convert
the elements of a model that conform to a particular metamodel, into elements of another model which
can be confirmed by the same or different metamodels. Model transformations are specified as OCL
contracts between metamodel.
The following types of transformations can be distinguished:
PIM to PSM Refinement: It describes how a PIM that conforms to a MOF-metamodel is transformed into a PSM that conforms to a specialized MOF-metamodel for a specific platform.
PSM to ISM Refinement: It describes how a PSM (which conforms to a MOF-metamodel for
specific platform) is transformed into code (which conforms to a MOF-metamodel for a specific
object-oriented language).
ISM to PSM Anti-refinement: It describes how a code that conforms to an ISM metamodel is
transformed into a PSM that conforms to a specialized MOF metamodel for a specific platform.
PSM to PIM Anti-refinement: It describes how a PSM that conforms to a PSM metamodel is
transformed into a PIM.
Refactoring: It specifies how a model in a given level is transformed into a new restructured
model in the same level (for instance, PIM to PIM, PSM to PSM, ISM to ISM). The source and
target models conform to the same MOF-metamodel.
Figure 5 shows the different correspondences that may be held between several metamodel, instances
of metamodels and their interrelations via refinements, anti-refinements and refactorings in a reengineering process. It can be viewed as an MDA horseshoe model that describes the phases of architecture
recovery and architecture based development, MDA is the underlying architectural framework. It shows
how reengineering proceeds at different levels of abstraction: code representation, platform dependent
models, platform independent models and computation independent models. In particular, reengineering
includes a reverse engineering phase in which an abstraction of the software models to be reengineered
is expressed in terms of MDA models, and a forward engineering phase.
10
This book proposes a framework for reverse engineering that distinguishes three different abstraction
levels linked to models, metamodels and formal specifications.
The model level includes code, PSMs and PIMs. Transformations at this level are based on classical
static and dynamic analysis techniques.
The metamodel level includes MOF-metamodels that describe families of ISMs, PSMs and PIMs.
Every ISM, PSM and PIM conforms to a MOF-metamodel. Metamodel transformations are based on a
minimal subset of OMG standard metamodels that we called MDA Infrastructure.
The level of formal specification includes specifications of MOF-metamodels and metamodel
transformations by using the metamodeling language NEREUS that can be viewed as an intermediate
formal-language independent notation. It focuses on interoperability of formal languages in MDD and
would eliminate the need to define formalizations and specific transformations for each different formal
language.
We define a bridge between MOF-metamodels and NEREUS consisting of a system of transformation rules to convert automatically MOF into NEREUS. Figure 6 shows the relation between metamodel
specifications and NEREUS. Relevant techniques of software evolution, such as reuse and refactoring
ones have been integrated in a way that fits with MDA.
It is worth considering that although, we use as an intermediate notation NEREUS and specific
transformation rule systems, the ideas underlying this approach are independent of particular notations.
The bases of our approach are:
11
MDA-based reverse engineering environments are structured in the way depicted in Figure 7. There
is a common repository to store data of the system; in MDA is a MOF- metadata repository. This repository attempts to address the problem of sharing models between different software tools. There are
parsers, to extract information from source code, metamodel tools to extract metamodel representations
and model interchange tools. These tools focus on static analysis. Other tracer tools focus on dynamic
analysis. Traditional tools such as visualizers, analyzers, browsers and debuggers, use the repository as
their base information. Other tools that focus on formal specification and formal transformation also
need the MOF- repository and basic facilities for import/export. Libraries of pattern and components
must fit with MDA.
The following chapters include background, foundations of innovative MDA processes and challenges and strategic directions that can be adopted in the field of MDA-based reverse engineering and
software evolution. We analyze principles of reverse engineering within system evolution and, show
how to recover MDA-based designs and architectures. Different principles of reverse engineering are
covered, with special emphasis on consistency, traceability, testing and verification of systems that are
critical to safety, security and economic profits.
The main strength of our approach is to detect a common conceptual foundation for what we do in
MDA processes. From making these foundations explicit, better tools should emerge.
12
reFerenceS
ADM (2007). ADM Task Force. Architecture Driven Modernization Roadmap. Retrieved on July 20,
2009 from adm.omg.org
Aho, A., Sethi, R., & Ullman, J. (1985). Compilers: Principles, Techniques, and Tools (2nd ed.). Reading: Addison-Wesley.
ANSI-IEEE. (1984). ANSI/IEEE Software Engineering Standards: Std 729-1983, Std 730-1884, Std
828-1983, 829-1984, 830-1984. Los Alamitos: IEEE/Wiley.
Baxter, I., & Mehlich, M. (1997). Reverse Engineering is Reverse Forward Engineering. In Proceedings
of Fourth Working Conference on Reverse Engineering, Amsterdam, The Netherlands. Retrieved on July
20, 2009 from www.semdesigns.com/Company/Publications/WCRE97.pdf
Booch, G., Rumbaugh, J., & Jacobson, I. (2005). The Unified Modeling Language. User Guide (2nd ed.).
Reading: Addison-Wesley.
Brodie, M., & Stonebraker, M. (1995). Migration Legacy Systems: Gateways, Interfaces, and Incremental
Approach. Morgan Kauffman.
CASE. (2009). CASE Tools. Retrieved on July 20, 2009 from www.objectsbydesign.com/tools/umltools_byCompany.html
Chikofsky, E., & Cross, J. (1990). Reverse engineering and design recovery: A taxonomy. IEEE Software,
7(1), 1317. doi:10.1109/52.43044
Demeyer, S., Ducasse, S., & Nierstrasz, O. (2002). Object-Oriented Reengineering Patterns. Amsterdam:
Morgan Kaufmann.
Fowler, M. (1999). Refactoring: Improving the Design of Existing Programs. Reading: AddisonWesley.
Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1995). Design Patterns. Elements of Reusable
Object-Oriented Software. Reading: Addison-Wesley.
Krahn, H., Rumpe, B., & Volkel, S. (2008). MontiCore: Modular development of Textual Domain Specific Languages. In Proceedings of TOOLS (46), Lecture Notes in Business information Processing 11
(pp. 297-315). Heidelberg: Springer-Verlag.
Laplante, P., & Neill, C. (2005). Antipatterns: Identification, Refactoring and Management. Auerbach
Publications.
MDA. (2003). MDA Guide Version 1.0.1. In J. Miller & J. Mukerji (Eds.). Document omg/2003-06-01.
Retrieved on July 20, 2009 from www.omg.org/mda
MDA. (2005). The Model Driven Architecture. Retrieved on July 20, 2009 from www.omg.org/mda.
Mernik, M., Heering, J., & Sloane, A. (2005). When and how to develop domain-specific languages.
ACM Computing Surveys, 37(4), 316344. doi:10.1145/1118890.1118892
13
MOF. (2006). MOF: Meta Object facility (MOF ) 2.0. OMG Specification formal/2006-01-01. Retrieved on July 20, 2009 from www.omg.org/mof
OCL. (2006). OCL: Object Constraint Language. Version 2.0. OMG: formal/06-05-01.Retrieved on
July 20, 2009 from www.omg.org
OMG. (2009a). The Object Management Group Consortium. Retrieved on July 20, 2009 from www.
omg.org
QVT. (2008). QVT: MOF 2.0 Query, View, Transformation. Formal/2008-04-03. Retrieved on July 20,
2009 from www.omg.org
SEI. (2009) Carnegie Mellon- Software Engineering Institute. Reengineering: The Horseshoe Model.
Retrieved on July 20, 2009 from http://www.sei.cmu.edu/reengineering/Horseshoe_model.html
Sommerville, I. (2004). Software Engineering (7th ed.). Reading: Addison Wesley.
Tonella, P., & Potrich, A. (2005). Reverse Engineering of Object Oriented Code. Monographs in Computer Science. Heidelberg: Springer-Verlag.
UML. (2009a). Unified Modeling Language: Infrastructure. Version 2.2. OMG Specification formal/2009-02-04. Retrieved on July 20, 2009 from www.omg.org.
UML. (2009b). UML: Unified Modeling Language: Superstructure. Version 2.2. OMG Specification:
formal/2009-02-02. Retrieved on July 20, 2009 from www.omg.org
14
15
Chapter 2
Model Driven
Architecture (MDA)
intrOductiOn
The architecture of a system is a specification of software components, interrelationships, and rules for
component interactions and evolution over time.
In 2001 OMG, adopted an architecture standard, the Model Driven Architecture (MDA). MDA is an
architectural framework for improving portability, interoperability and reusability through separation
of concerns (MDA, 2003) (MDA, 2005). It is not itself a technology specification but it represents an
evolving plan to achieve cohesive model-driven technology specifications. MDA is built on OMG standards including the Unified Modeling Language (UML), the XML Metadata Interchange (XMI) (XMI,
2007) and CORBA (CORBA, 1992) (CORBA, 2002) a major middleware standard.
MDA is model-driven because it uses models to direct the complete lifecycle of a system. All artifacts such as requirement specifications, architecture descriptions, design descriptions and code, are
regarded as models. MDA provides an approach for specifying a system independently of the platforms
that it supports, specifying platforms, selecting a particular platform for the system, and transforming
the system specification into one implementation for the selected particular platform.
Why MDA? OMG has focused on the creation of open specifications to encourage application interoperability. It was defined to solve enterprise application integration. A middleware describes a piece
of software that connects two or more software applications, allowing them to exchange data. To achieve
this, it must be implemented for all different languages and platforms that need linking.
DOI: 10.4018/978-1-61520-649-0.ch002
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
With the emergence of internet applications, the interoperability problem moved from the integration
of platforms and programming languages on a company intranet to the integration of different middleware on Internet. In this situation, the middleware is part of the problem itself. The original inspiration
around the definition of MDA had to do with this internet middleware integration problem. Apart from
interoperability reasons, there are other good benefits to use MDA such as to improve the productivity,
code and processes quality and, software maintenance costs.
MDA defines a framework that separates the specification of the system functionality from its implementation on a specific platform. It distinguishes different kinds of models:
Computation Independent Model (CIM), a model that describes a system from the computation
independent viewpoint.
Platform Independent Model (PIM), a model with a high level of abstraction that is independent of any implementation technology.
Platform Specific Model (PSM), a tailored model to specify the system in terms of the implementation constructs available in one specific platform.
Implementation Specific Model (ISM), a description (specification) of the system in source
code.
The Unified Modeling Language (UML) (UML, 2009a) (UML, 2009b) combined with the Object Constraint Language (OCL) (OCL, 2006) is the most widely used way for writing either PIMs or PSMs.
Model Driven Development (MDD) refers to a range of development approaches that are based on the
use of software models as first class entities. (Sztipanovits and Karsai, 1997) and (Kulkarni and Reddy,
2005) describe approaches for MDD. Selic (2006) positions UML 2 as a model driven development tool.
Hailpern & Tarr (2006) illustrate the good, the bad and the ugly of MDD and improvements to meet
major challenges at all stages of the software life cycle. France and Rumpe (2007) describe a research
roadmap of MDD of complex software.
MDA is the specific realization of MDD proposed by OMG. It is carried out as a sequence of model
transformations: the process of converting one model into another one of the same system preserving
some kind of equivalence relation between them.
The idea behind MDA is to manage the evolution from CIMs to PIMs and PSMs that can be used to
generated executable components and applications. The high level models that are developed independently of a particular platform are gradually transformed into models and code for specific platforms.
The transformation for one PIM to several PSMs is at the core of MDA. A model-driven forward
engineering process is carried out as a sequence of model transformations that includes, at least, the
following steps: construct a CIM; transform the CIM into a PIM that provides a computing architecture
independent of specific platforms; transform the PIM into one or more PSMs, and derive code directly
from the PSMs.
The concept of formal metamodel has contributed significantly to some of the core principles of the
emerging MDA. The Meta Object Facility (MOF), an adopted OMG standard, (latest revision MOF 2.0)
provides a metadata management framework, and a set of metadata services to enable the development
and interoperability of model and metadata driven systems (MOF, 2006).
A metamodel is an abstract language for describing different types of models and data. The framework
for metamodeling is based on architectures with four meta-layers: meta-metamodel, metamodel, model
16
and object model layers. The primary responsibility of these layers is to define languages that describe
metamodels, models, semantic domains and run-time instances of model elements respectively.
Related OMG standard metamodels and meta-metamodels such as Meta Object Facility (MOF)
(MOF, 2006), Software Process Engineering Metamodel (SPEM) (SPEM, 2008) and Common Warehouse Metamodel (CWM) (CWM, 2003) share a common design philosophy. All of them, including
MOF, are expressed using MOF. It defines a common way for capturing all the diversity of modeling
standards and interchange constructs that are used in MDA. Its goal is to define languages in a same
way and hence integrate them semantically.
MOF and the core of the UML metamodel are closely aligned with their modeling concepts. The
UML metamodel can be viewed as an instance-of the MOF metamodel in the sense of each UML
metaclasses conforms to an instance of a MOF metaclass.
OMG adopted the MOF 2.0 Query, View and Transformation (QVT) metamodel (QVT) for expressing
transformations (QVT, 2008). A query selects specific elements of a model, a view is a model derived
from other model, and a transformation is a specification of a mechanism to convert the elements of
a model, into elements of another model, which conform the same or different metamodel.
MDA reverse engineering can be used to recover architectural models of legacy systems that will be
later used in forward engineering processes to produce new versions of the systems. OMG is involved
in a series of standards to successfully modernize existing information systems. Modernization supports,
but are not limited to, source to source conversion, platform migration, service oriented architecture
migration and model driven architecture migration. Architecture-Driven Modernization (ADM) is an
OMG initiative related to extending the modeling approach to the existing software systems and to the
concept of reverse engineering (ADM, 2007).
A lot of work has been conducted within the diffusion of MDA. (Kleppe & Warner, 2003) and (Mellor,
Scott, Uhl & Weise, 2003) are the first books that introduced the MDA approach. Other books provide
a set of readings on the state-of-the-art and the state-of-the-practice of MDA (Byededa, Book & Gruhn,
2005). (Raistrick, Francis & Wright, 2004) analyzes the automatic executable code generation directly
from model specifications using Executable UML (XUML).
Arlow and Neustad (2003) propose a practical guide to applying MDA and patterns in order to create
business applications more easily. It provides a proven catalog of archetype patterns to understand and
model a specific part of an enterprise system. (Hruby, 2006) shows how to apply the pattern ideas in
business applications and presents more than 20 structural and behavioral business patterns.
Guttman and Parodi (2006) describe six case studies of real companies illustrating the variety of
MDA approaches.
(Pastor & Molina, 2007) includes a software process based on model transformation technology
introducing information required to put MDA into the industrial practice.
17
A CIM describes a system from the computation independent viewpoint that focuses on the environment of and the requirements for the system. It is independent of how the system is implemented.
In general, it is called domain model and may be expressed using business models. The CIM helps to
bridge the gap between the experts about the domain and the software engineer. A CIM could consist of
UML models and other models of requirements.
In the context of MDA, a platform is a set of subsystems and technologies that provides a coherent
set of functionality through interfaces and specified usage patterns, which any application supported by
that platform can use without concern for the details of how the functionality provided by the platform is
implemented (MDA, 2003, pp. 2-3). An application refers to a functionality being developed. A system
can be described in terms of one or more applications supported by one or more platforms. MDA is based
on platform models expressed in UML, OCL, and stored in a repository aligned with MOF.
A PIM is a view of the system that focuses on the operation of a system from the platform independent viewpoint. Analysis and logical models are typically independent of implementation and specific
platforms and can be considered PIMs.
A PIM is defined as a set of components and functionalities, which are defined independently of
any specific platforms, and which can be realized in platform specific models. A PIM can be viewed as
a system model for a technology-neutral virtual machine that includes parts and services defined independently of any specific platform. It can be viewed as an abstraction of a system that can be realized
by different platform-specific ways on which the virtual machine can be implemented.
A PSM describes a system in the terms of the final implementation platform e.g., .NET or J2EE. A
PSM is a view of the system from the platform specific viewpoint that combines a PIM with the details
specifying how that system uses a particular type of platform. It includes a set of technical concepts
representing the different parts and services provided by the platform.
An ISM is a specification, which provides all the information needed to construct an executable
system.
18
Although there is a structural gap between CIM and PIM, a CIM should be traceable to PIM. In the
same way, a PIM should be traceable to PSMs which in turn should be traceable to ISMs.
Metamodels
Metamodeling is a powerful technique to specify families of models. A metamodel is a model that defines the language for expressing a model, i.e. a model of models. A metamodel is an explicit model
of the constructs and rules needed to build specific models. It is a description of all the concepts that
can be used in a model.
A meta-metamodel defines a language to write metamodels. Since a metamodel itself is a model, it
can be usually defined using a reflexive definition in a modeling language. A metamodel can be viewed
as a model of a modeling language.
Metamodeling has become an essential technique in MDA. In particular, MDA is based on the use
of a language to write metamodels called the Meta Object Facility (MOF). MOF uses an object modeling framework that is essentially a subset of the UML 2.2 core. The four main modeling concepts are
classes, which model MOF metaobjects; associations, which model binary relations between metaobjects; Data Types, which model other data; and Packages, which modularize the models (MOF, 2006)
(MOF, 2002).
The UML itself is defined using a metamodeling approach. The metamodeling framework for the
UML is based on a modeling architecture with four layers: meta-metamodel, metamodel, model and user
objects. A model is expressed in the language of one specific metamodel. A metamodel is an explicit
model of the constructs and rules needed to construct specific models. Meta-metamodel are usually
self-defined using a reflexive definition that is based at least on three concepts (entity, association and
package) and a set of primitive types. Languages for expressing MOF-based metamodels are based on
UML class diagrams and OCL constraints to rule out illegal models.
19
Transformations
Model transformation is the process of converting one model into another model of the same system
preserving some kind of equivalence relation between both of these models. Figure 2 shows how a
platform independent model (PIM) and a platform component description (PDM) are combined by the
transformation to produce a platform specific model (PSM).
We can distinguish three types of transformations to support model evolution in forward and reverse
engineering processes: refinements, anti-refinements and refactorings.
A refinement is the process of building a more detailed specification that conforms to another that is
more abstract. On the other hand, an anti-refinement is the process of extracting from a more detailed
specification (or code) another one, more abstract, that is conformed by the more detailed specification.
Refactoring means changing a model leaving its behavior unchanged, but enhancing some non-functionality
quality factors such as simplicity, flexibility, understandability and performance.
Metamodel transformations are contracts between a source metamodel and a target metamodel and
describe families of transformations.
Figure 3 partially depicts the different kind of transformations and the relationships between models
and metamodels.
uML MetaMOdeL
UML have emerged as a de-facto standard for expressing object-oriented models. It is a graphical
language for visualizing, specifying, constructing and, documenting the artifacts of software intensive
systems that can be used with all major object and component methods, and can be applied to a large
and diverse set of domains (e.g. healthcare, finance, telecom, aerospace) and implementation platforms
20
(e.g. .NET, relational or different Java platforms) (Rumbaugh, Jacobson, & Booch, 1998) (Booch,
Rumbaugh & Jacobson, 2005).
Although UML does not prescribe any particular development process, various companies are working on processes to provide advice on the use of UML in the software development life cycle.
The OMG presents the Software Process Engineering Metamodel (SPEM) (SPEM, 2008). This
metamodel is used to describe a concrete software development process or a family of related software
development process. Several processes enact SPEM. The most popular is Rational Unified Process
(RUP), developed and marketed by Rational Software. It is a software development process based on
UML that is a use-driven, architecture centered, iterative and risk driven. It provides a disciplined
approach to assigning tasks and responsibilities within a development organization. RUP is organized
around four phases (inception, elaboration, construction and transition) and core workflows (require-
21
Behavioral Diagrams
Class Diagram
Object Diagram
State Diagram
Component Diagram
Communication Diagram
Sequence Diagram
Package Diagram
Activity Diagram
Deployment Diagram
Timing Diagram
Interaction Diagrams
ments, capture, analysis, design, implementation and test). Various industry sectors around the world use
RUP in different applications: telecommunications, transportation, aerospace, defense, manufacturing
and financial services (Jacobson, Booch, & Rumbaugh, 1999) (Kruchten, 2000).
UML supports different diagrams that can be used for modeling different views of the system under
development. Table 1 summarizes the different kinds of UML static and behavioral diagrams. A detailed
analysis of them may be found at (Booch, Rumbaugh & Jacobson, 2005).
The latest version 2.2 of UML is defined in terms of the UML 2. 2. Infrastructure and UML 2. 2
Superstructure (UML, 2009a) (UML, 2009b).
22
Core package is composed by four main packages: PrimitiveTypes, Abstractions, Basic, and Constructs as shown in Figure 6.
The package PrimitiveTypes contains the primitive types that are used when metamodeling in
the context of UML and MOF. In order to facilitate reuse, the package Abstractions contains abstract
metaclasses commonly reused or specialized by many metamodel. The package Constructs contains
concrete metaclasses linked to object-oriented modeling and reflects a central part of the alignment
of UML and MOF. The package Basic defines constructs that are used as the basis for the produced
XMI for metamodels based on the InfrastructureLibrary. While instantiation of metaclasses is carried
out through MOF, the InfrastructureLibrary defines the actual metaclasses that are used to instantiate
the elements of metamodels such as UML, and indeed the elements of the InfrastructureLibrary itself.
Then, it is reflective. All of the UML metamodel is instantiated from meta-metaclasses that are defined
in the InfrastructureLibrary.
The Profiles Package depends on the Core package and define the mechanisms that allow metaclasses
from existing metamodel to be extended to adapt for different purpose languages/platforms such as C++,
Figure 6. The Core packages
23
CORBA (CORBA, 2002), or EJB (EJB, 2004); or domains such as real-time, business objects, or software process modeling. In general, profiles are associated to UML, but it is possible to define profiles
in terms of a metamodel that is based on the common core (see Figure 5).
The Infrastructure has aligned architecturally UML and MOF. Figure 7 shows UML and MOF at different metalevels. UML is defined as a model based on MOF in which each UML metaclass is an instance
of a MOF metaclass. Also, MOF is the metamodel of other OMG standards e.g. CWM and SPEM.
24
Figure 8. The top level package structure of the UML Superstructure 2.1.2
uML Semantics
UML semantic specification is defined using a metamodeling approach that combines MOF-based metamodels, OCL specification and text. The metamodel is described in a semi-formal way using abstract
syntax, well-formed rules and semantics. The abstract syntax is provided as a model expressed by UML
class diagram and a natural language description. The class diagram shows the metaclasses defining the
constructs and their relationships. The well-formed rules are expressed in OCL and natural language.
25
does not define any classes of its own. Rather, it merges packages with its extensions that together define
basic metamodeling capabilities.
The four modeling concepts in MOF are:
The traditional metamodel architecture is four-layer metadata architecture however this hierarchy
could be based on more levels. Strength of metamodels is the possibility to define more abstraction levels.
Besides, a model (a collection of metadata) is not necessarily limited to one meta-level. For instance a
reverse engineering process that requires code transformations could describe an ISM by four layers.
The topmost layer M3 is an EBNF (the meta-metamodel), the M2 layer is a specific grammar (the metamodel), the M1 layer a Java program and M0 an execution model, the entity in the real world.
The MOF model is self-describing, that is to say it is formally defined using its own metamodeling
constructs. This provides a uniform semantic treatment between artifacts that represent models and
metamodels.
26
FOur-LaYer architecture
The MDA is based on four meta-layer architectures. The layers are conventionally identified as M3, M2,
M1 and M0 layers. Figure 10 exemplifies the MOF metadata architecture based on four layers.
The M3 layer is the meta-metamodel and MOF is an example of meta-metamodel. MOF is a framework
for specifying, constructing, and managing independent metamodels. It is the basis to define modeling
languages such as UML or MOF itself. A meta-metamodel describes a family of metamodels. In general,
metamodels and meta-metamodels share a common design philosophies and constructs. However, each
layer can be viewed independently of others layers
All metamodels that conform to a meta-metamodel are placed in the M2 layer. UML and SPEM
metamodel (SPEM, 2008) are examples of metamodel that conforms to MOF. The metamodels of this
layer describe families of models of the real world, which are represented in the M1 level. A model is
an instance of a metamodel. M1 is a model layer that defines languages. UML models, that conform
to UML metamodel, and the IBM Rational Unified Process (RUP) that conforms to SPEM are in M1
(Krutchen, 2000) (SPEM, 2008). A user model is an instance of the UML metamodel. M1 contains both
model elements and snapshots of instances of these model elements.
The bottom most layer is the instance layer M0 that contains run-time instances of the concepts
defined in M1 layer.
The information layer includes the data that we wish to describe; the data in the information layer
are described in the model layer; the metamodel layer is comprised of the descriptions that define the
structure and semantics of metadata and, the meta-metamodel layer is comprised of the description of
the structure and semantics of meta-metadata.
27
Query: ad-hoc query for selecting and filtering of model element. In general, a query selects
elements of the source model of the transformation
View: views of MOF metamodels (that are involved in the transformation)
Transformation: a relation between a source metamodel S and a target metamodel T that is used
to generate a target model (that conforms to T) from a source model (that conforms to S).
QVT defines a standard for transforming a source model into a target model. One of the underlying
ideas in QVT is that the source and target model must conform to arbitrary MOF metamodels. Another
one is that the transformation is considered itself as a model that conforms to a MOF metamodel.
The QVT specification includes three main packages: QVTCore, QVTRelation and QVTOperations. These packages depends on another intermediate QVT packages (QVTBase, QVTTemplate and
ImperativeOCL), EMOF and EssentialOCL. Figure 11 shows dependencies of packages in the QVT
specification (QVT, 2008, pp. 12). EMOF is a subset of MOF that allows simple metamodels to be
defined using simple concepts while supporting extensions for more sophisticated metamodeling using
CMOF (see Figure 9). Essential-OCL (OCL, 2006, pp. 171) is a package exposing the minimal OCL
required to work with EMOF (MOF, 2006, pp. 31).
A transformation defines how one set of models can be transformed into another. It is composed by
a set of rules that specify its execution behavior. Also, it includes a set of typed model parameters associated with the transformation. Syntactically, a transformation is a subclass of both a Package and a
Class. A transformation can extend another transformation. A rule domain is the set of model elements
Figure 11. Packages and dependencies in QVT
28
of a typed model that are of interest to it. A domain may be marked as checkable or enforceable. A
checkable domain declares that the owning rule is only required to check whether the model elements
specified by the domain exist in the target model and report errors when they do not. An enforceable
domain declares the owning rule must ensure that the model elements specified by the domain exist in
the target model (QVT, 2008, pp. 27).
The QVT specification has a hybrid declarative/imperative nature. Figure 11 shows the relationships
between the QVT metamodel.
The declarative part of this specification is structured in two layers:
A user-friendly Relations metamodel and language which supports the creation of object template,
complex object pattern matching and the creation of traces between model elements involved in
a transformation.
A Core metamodel and language defined using minimal extensions to EMOF and OCL. All trace
classes are explicitly defined as MOF models, and trace instance creation and deletion in the same
way as the creation and deletion of any other object.
Relations metamodel includes a declarative specification of the relationships between MOF models.
The Relations language supports complex object pattern matching, and implicitly creates trace classes
and their instances to record what occurred during a transformation execution. Relations can assert that
other relations also hold between particular model elements matched by their patterns.
Core is a small model/language which only supports pattern matching over a flat set of variables by
evaluating conditions over those variables against a set of models. It treats all of the model elements of
source, target and trace models symmetrically. It is equally powerful to the Relations language, and because
of its relative simplicity, its semantics can be defined more simply, although transformation descriptions
described using the Core and therefore more verbose. In addition, the trace models must be explicitly
defined, and are not deduced from the transformation description, as is the case with Relations.
The core model may be implemented directly, or simply used as a reference for the semantics of
Relations, which are mapped to the Core, using the transformation language itself.
The Relational language has a textual and graphical concrete syntax. Figure 12 shows the relationships
between the QVT metamodel. A transformation between source models is specified as a set of relations
that must be hold for the transformation to be successful. Source models are named, and the types of elements they can contain are restricted to those within a set of referenced packages. A transformation can
be invoked either to check two models for consistency or to modify one model to enforce consistency.
In addition to the declarative Relations and Core languages which embody the same semantics at
two different levels of abstraction, there are two mechanisms for invoking imperative implementations
of transformations: one standard language, Operational mappings, as well as non-standard Black-box
MOF Operation implementations.
The first is an imperative language whose syntax provides constructs commonly found in imperative languages. The latter allows invoking transformation facilities expressed in other languages. It is a
crucial mechanism for integrating non-QVT libraries with QVT transformations.
At this time QVT standard only addresses model to model transformations. In this context a model
means some entity conforming to any MOF 2.0 metamodel.
29
30
are specific kinds of packages. A stereotype can be viewed as a metatype, because it allows creating
new elements of UML metamodel. A tag definition can be attached to model elements. They can be
viewed as metadata definitions, because they extend the properties of a UML element, creating new
information in the element metaclass. The actual values of the properties of particular elements are
called tagged values. A constraint extends the semantics of a UML element, adding new constraints or
modifying existing ones.
More detail of the extension mechanisms may be found at (Booch, Rumbaugh & Jacobson, 2005)
and (UML, 2009b).
(EJB, 2004) describes the Enterprise JavaBeans metamodel and the Java metamodel and shows how
each metamodel element can be mapped to profile representations. Many profiles have been adopted by
OMG, such as the UML Profile for CORBA (CORBA, 2002) and EJB. Other profiles have been accepted
by the software community such as the UML profile for Web applications (Conallen, 2002).
MOF supports first-class extensibility that allows adding and removing metaclasses and relationships.
The mechanisms for first-class extensibility and profiles start fusing when methodology restrictions that
prevent to modify existing metamodel are applied.
There are multiple factors that determine when we should create a new metamodel and when we
instead should create a profile. Tools that implement MOF 2.0 will allow users to define entirely new
languages via metamodel or profiles. For instance Domain Specific Language (DSL) may be defined
by using a standard MOF foundation (Mernik, Heering & Sloane, 2005).
A domain-specific language (DSL) allows us to solve problems in a particular domain and is not
intended to be able to solve problems outside it. DSLs can be based on the profiles mechanisms or new
metamodel. In both cases, MOF foundation brings the benefits of metamodeling tool standards. As examples of these situations, we can mention OMG standards System Modeling Language (SysML) (SysML,
2008) and the Semantics of Business Vocabulary and Business Rules (SBVR) (SBVR, 2008).
On the one hand, SysML is a DSL for systems engineering. It supports the specification, analysis,
design, verification and validation of complex systems that include hardware, software, information and
processes. SysML is defined as an extension of a subset of UML diagrams by using the UML profile
mechanism.
On the other hand, SBVR is an adopted standard of OMG for representing business rules. It has its
own notation to formalize complex compliance rules, such as operational rules for an enterprise, security
policy, standard compliance, or regulatory compliance rules. It was defined as a MOF metamodel.
reFerenceS
ADM (2007). ADM Task Force. Architecture Driven Modernization Roadmap. Retrieved on July 20,
2009 from adm.omg.org
Arlow, J., & Neustad, I. (2003). Enterprise Patterns and MDA: Building Better Software with Archetype
Patterns and UML. Reading: Addison-Wesley.
Beydeda, S., Book, M., & Gruhn, V. (2005). Model Driven Software Development. Heildelberg: SpringerVerlag.
31
Booch, G., Rumbaugh, J., & Jacobson, I. (2005). The Unified Modeling Language. User Guide (2nd ed.).
Reading: Addison-Wesley.
Conallen, J. (2002). Building Web Applications with UML (2nd ed). Reading: Addison-Wesley.
CORBA. (1992). Common Object Request Broker Architecture (CORBA) V. 1.1. Retrieved on July 20,
2009 from www.corba.org
CORBA. (2002). UML Profile for Corba, version 1.0. Document: formal/02-04-01. Retrieved on July
20, 2009 from www.omg.org
CWM. (2003).Common Warehouse Metamodel, v. 1.1 formal/2003-03-02. Retrieved on July 20, 2009
from www.omg.org/spec/cwm
EJB. (2004). Metamodel and UML Profile for Java and EJB Specification. Document: formal/04-02-02.
Retrieved on July 20, 2009 from www.omg.org
France, R., & Rumpe, B. (2007). Model-driven Development of Complex software: A Research Roadmap. In Proceedings of the Future of Software Engineering (FOSE 2007) (pp. 37-54). Los Alamitos:
IEEE Computer Society.
Guttman, M., & Parodi, J. (2006). Real-Life MDA: Solving Business Problems with Model-Driven Architecture. Morgan Kaufmann OMG Press.
Hailpern, B., & Tarr, P. (2006). Model-driven development: The good, the bad, and the ugly. IBM Systems Journal, 45(3), 451461.
Hruby, P. (2006). Model Driven Design using Business Patterns. Heidelberg: Springer.
Jacobson, I., Booch, G., & Rumbaugh, J. (1999). The Unified Software Development Process. Reading:
Addison-Wesley.
Kleppe, A., Warmer, J., & Bast, W. (2003). MDA Explained: The Model Driven Architecture: Practice
and Promise. Reading: Addison-Wesley.
Kruchten, P. (2000). The Rational Unified Process: An Introduction (2nd Ed.). Reading: Addison Wesley
Professional.
Kulkarni, V., & Reddy, S. (2005). Model Driven Development of Enterprise Applications (LNCS 3297,
pp. 118-128). Heidelberg: Springer-Verlag.
MDA. (2003). MDA Guide Version 1.0.1. In J. Miller & J. Mukerji (Eds.). Document omg/2003-06-01.
Retrieved on July 20, 2009 from www.omg.org/mda
MDA. (2005). The Model Driven Architecture. Retrieved on July 20, 2009 from www.omg.org/mda.
Mellor, S., Scott, K., Uhl, A., & Weise, D. (2003). MDA Distilled: Principles of Model Driven Architecture. Addison-Wesley.
Mernik, M., Heering, J., & Sloane, A. (2005). When and how to develop domain-specific languages.
ACM Computing Surveys, 37(4), 316344. doi:10.1145/1118890.1118892
32
MOF. (2002). Meta Object Facility (MOF) Specification version 1.4. Document formal/01-11-02. Retrieved on July 20, 2009 from www.omg.org
MOF. (2006). MOF: Meta Object facility (MOF ) 2.0. OMG Specification formal/2006-01-01. Retrieved on July 20, 2009 from www.omg.org/mof
OCL. (2006). OCL: Object Constraint Language. Version 2.0. OMG: formal/06-05-01.Retrieved on
July 20, 2009 from www.omg.org
Pastor, O., & Molina, J. (2007). Model-Driven Architecture in Practice: A Software production Environment Based on Conceptual Modeling. Heidelberg: Springer-Verlag.
QVT. (2008). QVT: MOF 2.0 Query, View, Transformation. Formal/2008-04-03. Retrieved on July 20,
2009 from www.omg.org
Raistrick, C., Francis, P., & Wright, J. (2004). Model Driven Architecture with Executable UML. Cambridge University Press.
Rumbaugh, J., Jacobson, I., & Booch, G. (1998). The Unified Modeling Language Reference Manual.
Reading: Addison-Wesley.
SBVR. (2008). Semantics of Business Vocabulary and Business Rules (SBVR), v1.0. Document: formal/2008-01-02. Retrieved on July 20, 2009 from http://www.omg.org/spec/SBVR/1.0/PDF
Selic, B. (2006). UML 2: A model-driven development tool. IBM Systems Journal, 45(3), 607620.
SPEM. (2008). Software & Systems Process Engineering Meta-Model Specification (SPEM) version 2.0.
Document: formal/2008-04-01. Retrieved on July 20, 2009 from http://www.omg.org/spec/SPEM/2.0/
PDF
SysML (2008) OMG System Modeling Language. version 1.1.Document: formal/2008-11-01. Retrieved
on July 20, 2009 from http://www.omg.org/spec/SysML/1.1/.
Sztipanovits, J., & Karsai, G. (1997). Model Integrated Computing. IEEE Computer, 30(4), 110112.
UML. (2009a). Unified Modeling Language: Infrastructure. Version 2.2. OMG Specification formal/2009-02-04. Retrieved on July 20, 2009 from www.omg.org.
UML. (2009b). UML: Unified Modeling Language: Superstructure. Version 2.2. OMG Specification:
formal/2009-02-02. Retrieved on July 20, 2009 from www.omg.org
XMI. (2007). MOF 2.0 / XMI Mapping, Version 2.1.1. Document: formal/2007-12-01. Retrieved on July
20, 2009 from http://www.omg.org/spec/XMI/2.1/PDF
33
34
Chapter 3
MDA, Metamodeling
and Transformation
intrOductiOn
MDA requires the ability to understand different languages such as general purpose languages, domain
specific languages, modeling languages or programming languages. An underlying principle of MDA
for integrating semantically in a unified and interoperable way such languages is using metamodeling
techniques.
A metamodel describes a family of models whose elements are instances of the metaclasses of the
respective metamodel. The kind of entities and relations defines the kind of metamodel, for instance:
An ISM-Java metamodel includes entities (metaclasses) for classes, fields, operations, methods,
constructors, parameters and interfaces. Methods and constructors are subtypes of operations.
Interfaces are associated with classes.
A PSM-Java metamodel distinguishes entities such as Java-metamodel entities and another entities such as associations.
A RDBMS metamodel includes entities for schema, table, column, key and foreign key.
The OMG standard for defining models is the Meta-Object-Facility (MOF) metamodel (MOF, 2006).
MOF is essential to define different modeling languages and metamodeling languages such as UML or
MOF itself. It allows capturing all the diversity of modeling standards and interchange constructs that
are used in MDA. A MOF-aware modeling tool can capture UML diagram elements in machine readable
form allowing tools from multiple vendors to be used together on a single project.
DOI: 10.4018/978-1-61520-649-0.ch003
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
The initial diffusion of MDA was focused on its relation with UML as modeling language. However,
there are UML users who do not use MDA, and MDA users who use other modeling languages such as
Domain Specific Languages (DSL).
The essence of MDA is MOF that allows different kinds of software artifacts to be used together in a
single project. It allows capturing all the diversity of modeling standards and interchange constructs that
are used in MDA. MOF provides a metadata management framework, and a set of metadata services to
enable the development and interoperability of models and metadata driven systems.
MOF cOnStructS
The MOF modeling concepts are classes, which model MOF meta-objects; associations, which model
binary relations between meta-objects; Data Types, which model other data; and Packages, which modularize the models (MOF, 2006, pp. 2-6). OCL can be used to attach consistency rules to metamodel
components.
Next, we describe these constructs in detail.
classes
Classes are type descriptions of first class instance MOF meta-objects. Instances of classes have object
identity, state, and behavior. Classes can have three kinds of features which are attribute, operation and
reference. They can also contain exceptions, constants, data types, constraints and other elements.
An attribute has properties such as type, name and multiplicity. Besides, it can contain flags such as
isChangeable and isDerived. The first determines whether the client is provided with an explicit
operation to set the attribute values and the latter, determines whether the contents of the notational value
holder is derived from other state.
Operations are hooks for describing the class behavior. They simply specify the name, the type
signatures by which the behavior is invoked. Operations have the following properties: name, a sequence
of parameters including name, type and multiplicity, an optional return type and, a list of Exceptions that
can be raised by an invocation. An attribute may be an optional-valued, single-valued, or multi-valued
depending on its multiplicity specification. The multiplicity can also include the flags is-Ordered for
indicating ordered attributes and is-unique for indicating whether instances with equal value are allowed in the given attribute or parameter.
Like UML, MOF provides class generalization. However, MOF imposes restrictions on generalization to ensure that it can be transformed into a range of implementation technologies:
MOF uses abstract class in the same sense as UML and other object-oriented programming languages.
35
A class may be defined as leaf or root. Declaring a class as a leaf prevents the existence of subclasses. Declaring a class as a root prevents the declaration of any superclasses.
Binary associations
Like UML, MOF provides associations, although there are no association classes and only binary associations are allowed. Each MOF association contains precisely two association-ends that include properties
such as name, type, multiplicity, navigability, changeability and, aggregation specification.
MOF supports two kinds of aggregation for relationships between instances: composite and nonaggregate. The semantic of shared-aggregation is not supported in MOF.
A non-aggregate relationship has the following properties:
On the contrary, a composite aggregation is a stronger link between instances with the following
properties (MOF, 2006):
A composite relationship is asymmetrical, with one end denoting the role of whole in the relationship (composite) and the other one denoting the parts (components)
An instance cannot be a component of more than one composite at a time, under any composite
relationship.
The relationships impacts on the lifecycle of the whole and its parts. When a composite instance
is deleted, all of its components under any composite relationship (directly or transitively) are also
deleted.
The Composition Closure rule: The composite and component instances in a composition along
with any links that form the composition must all belong to the same outermost Package extent.
The effective semantics for an attribute depends on the type of attribute. A non-aggregate semantics
correspond to an attribute whose type is expressed as a data Type. On the other hand, an attribute whose
type is expressed as a Class has a composite semantics.
data types
Metamodels often requires using attribute and operation parameter values that have types whose values
do not have object identity. Considering this, MOF provides the metamodeling concept of Data Type.
Data Types can represent two kinds of data type:
36
Packages
The package is the MOF mechanism for grouping elements into a metamodel. A package can contain
different model elements such as packages, classes, associations and data types. It provides four structuring mechanisms: generalization, nesting, importing and clustering.
Generalization is similar to class generalization in MOF. However, packages may be defined as root
or leaf packages, but abstract packages are not supported.
A nested package is a component of its enclosing package. There are some restrictions on nesting
relationships, nested packages do not admit generalization, importing or clustering relations with other
packages. Conceptually, a nested package instance is a component of an instance of the containing package and, they can not be directly instantiated.
When one package imports another, the importing package is allowed to make use of elements defined
in the imported one package. Package clustering can be viewed as a stronger form of package import
that links imported packages into a cluster.
eXaMPLeS
In order to illustrate the use of MOF language, this section includes MOF-based metamodels for three
popular object oriented languages JAVA, C++ and Eiffel. Although, these examples only specify a part
of MOF metamodel, we introduce now the notation used in the following chapters of this book for
describing metamodels.
Metamodel notation
Metamodels are specified by using the UML notation including an abstract syntax and metaclass descriptions.
The abstract syntax consists of one or more UML class diagrams that show the package including
metaclasses, their constructs and interrelationships. A number of metaclasses from the UML Infrastructure
are imported. These metaclasses are shown in the models with a transparent fill color.
The description of a metaclass starts with an informal definition of the metaclass that sets the context
for the definition. This description is followed by a description of generalizations, attributes and associations. Each of them is enumerated together with a short explanation. The multiplicity of attributes and
associations is enclosed in square brackets.
The description includes well-formedness rules expressed in OCL. These rules are defined as a
(possibly empty) set of invariants for the metaclass, which must be satisfied by all instances of that
metaclass for the model to be meaningful The OCL expressions thus specify constraints over attributes
and associations defined in the metamodel. The statement No additional constraints means that all wellformedness rules are expressed in the superclasses together with the multiplicity and type information
expressed in the diagrams. Constraints are specified in EssentialOCL (OCL, 2006).
In many cases, additional operations on the classes are needed for the OCL expressions. These are
then defined in a separate subsection after the constraint section using comments followed by the OCL
expression defining the operation.
37
Metamodels are specified in the style proposed in the OMG documentation for the different standards.
The structure of the text describing a metaclass is as follows:
<className>
Description
< text>
Generalizations
< generalizationList>
Attributes
< attributeList>
Associations
<associationList>
Constraints
<constraintList>
Additional Operations
<additionalOperationList>
Appendix C includes an overview of OCL, in particular EssentialOCL (OCL, 2006, pp. 171-176). A
detailed description may be found at (OCL, 2006)
Attributes
38
isDeferred: Boolean [1] It specifies whether a class is deferred, i.e., it includes one or more features that are specified but no implemented. It redefines Classifier::isAbstract.
isExpanded: Boolean [1] It specifies whether the class is flattened, i.e. its instances are objects but
no references to objects.
isObsolete: Boolean [1] It specifies whether the class is obsolete.
Associations
attribute: Attribute [*] It refers to the own attributes of the Eiffel class. It redefines
Class::ownedAttribute.
eiffelFeatures: EiffelFeature [*] It refers to the features of which this class is client.
generalization: Generalization [*] It specifies the generalization for this class.
invariant: Assertion [*] It refers to invariants of the class. It redefines NameSpace::ownedRule.
ownedRoutine: Routine [*] It refers to the own routines of the class. It redefines
Class::ownedOperation.
/parameters: EiffelParameter [*] It refers to the set of parameters of the class. It is derived.
/parent: EiffelClass [*] It refers to the parent class of an Eiffel class. It redefines Class::superClass.
It is derived.
Constraints
[1] A class having a deferred routine must be declared deferred. self.ownedRoutine -> exists (r |
r.isDeferred) implies self. isDeferred
39
[2] Secret routines can not be declared deferred. self.ownedRoutine -> forAll (r | r.availability = #secret
implies not r.isDeferred)
[3] Frozen routines can not be declared deferred. self.ownedRoutine -> forAll (r | r.isFrozen implies
not r.isDeferred)
[4] An Eiffel class does not have nested classes. self.nestedClassifier -> isEmpty()
[5] ancestors is derived of the generalization. ancestors = self.generalization.parent
[6] parameters is derived from the parameters of the template signature that is redefinable. parameters
= ownedSignature.parameter
[7] Parameters of a class are of the type Eiffel class. self.parameters.parameteredElement -> forAll
(p | p.oclIsTypeOf (EiffelClass))
[8] A deferred class does not have a creation procedure. self.class.isDeferred implies self.ownedRoutine -> select(p | p.oclIsTypOf (Procedure) and p.isCreator) -> isEmpty()
[9] A flattened class has only a creation procedure without arguments. self.class.isExpanded implies
self.ownedRoutine -> select(p| p.oclIsTypeOf (Procedure) and p.isCreator) -> size() = 1 and self.
ownedRoutine -> select(p | p.isCreator and p.argument -> isEmpty()) -> size() = 1
[10] A flattened class does not have parameters. self.class.isExpanded implies self.parameter ->
isEmpty()
Attributes
40
class-key: Class-Key [1] It specifies the type of the class, i.e., if it is a class, structure or union.
isFinal: Boolean [1] It specifies whether the class has subclasses. It redefines
RedefinableElement::isLeaf.
/isGeneric: Boolean It specifies whether the class is generic. It is a derived attribute.
Associations
variable: Variable [*] It refers to the own variables of the C++ class. It redefines
Class::ownedAttribute.
nestedClass: C++Class [*] It refers to the C++ classes that are declared within the body of a C++
class (nested classes). It is a subset of Class::nestedClassifier.
/superClass: C++Class [*] It refers to the superclasses of a C++ class. It redefines Class::superClass.
It is derived.
function: C++MemberFunction [*] It refers to the own functions of the class. It redefines
Class::ownedOperation.
generalization: C++Generalization [*] It refers to the generalizations of the class. It redefines
Class::Generalization.
friendClass: C++Class [*] It refers to the friend classes of the class.
friendFunction: C++Function [*] It refers to the friend functions of the class.
/parameters: C++Parameter [*] It refers to the set of parameters of the class. It is derived.
41
Constraints
[1] A class that has pure virtual functions must be declared abstract. self.function -> select
(oclIsTypeOf(Method)) -> exists (m | m.oclAsType (Method).isPureVirtual) implies self.
isAbstract
[2] A class declared final does not have subclasses, i.e, it is not superclass of any class belonging to
the package. self.isFinal implies self.package.ownedMember -> select (oclIsTypeOf(C++Class))
-> forAll (c | c.oclAsType(C++Class).superClass <> self)
[3] Private functions of a class can not be declared abstract. self.function -> select (oclIsTypeOf(Method))
-> forAll (m | m.visibility = #private implies not m.oclAsType(Method).isPureVirtual)
[4] Final methods of a class can not be declared abstracts. self.function -> select (oclIsTypeOf(Method))
-> forAll (m | m.oclAsType(Method).isFinal implies not m.oclAsType(Method).isVirtual)
[5] A class is generic if it has a signature template. isGeneric = (self.ownedTemplateSignature -> size
() =1)
[6] parameters is derived from the parameters of the signature template that are redefinable. /parameters= self.ownedTemplateSignature.parameter
[7] Friend functions are C++ functions but no member functions of a class. self.friendFunction ->
forAll (f | f.isTypeOf (C++Function))
[8] A class only has a destructor. self.function -> select (oclIsTypeOf (Destructor)) -> size () <= 1
Attributes
42
isFinal: Boolean It specifies whether the class can have subclasses. It redefines
RedefinableElement::isLeaf.
/isGeneric: Boolean It specifies whether the class is generic. It is a derived attribute.
isStatic: Boolean It specifies whether the class is static.
Associations
field: Field [*] It refers to the own variables of the Java class. It redefines Class::ownedAttribute.
/implement: It refers to the Java interfaces that are implemented by this class. It is derived.
javaOperation: JavaOperation [*] It refers the own operations of the class. It redefines
Class::ownedOperation.
javaPackage: JavaPackage [0..1] It refers to the package in which is declared. It redefines
Type::package.
nestedClass: JavaClass [*] It refers to the Java classes that are declared within the body of a Java
class (nested classes). It is a subset of Class::nestedClassifier.
nestedInterface: JavaInterface [*] It refers to the Java interfaces that are declared within the body
of a JavaClass (nested interfaces). It is a subset of Class::nestedClassifier.
/parameters: JavaParameters [*] It refers to the set of parameters of a class. It is derived.
/superClass: JavaClass [1] It refers to a superclass of a Java class. It redefines Class::superClass.
It is derived.
Constraints
[1] Nested classifiers belonging to a class or interface can only be of type JavaClass or JavaInterface. self.
nestedClassifier -> forAll (c | c.oclIsTypeOf (JavaClass) or c.oclIsTypeOf (JavaInterface))
[2] The implemented interfaces are those referred through the interface realization. implement = self.
interfaceRealization.contract
43
[3] A class that has some abstract method must be declared abstract. self.javaOperation -> select
(op| op.oclIsTypeOf(Method)) -> exists (m | m.oclAsType(Method).isAbstract) implies self.
isAbstract
[4] An abstract class does not have a constructor defined explicitly. self.isAbstract implies self.javaOperation -> select(op| op.oclIsTypeOf (Constructor)) -> isEmpty()
[5] A class that is declared final can not have subclasses, i.e., it is not superclass of any class in the package. self.isFinal implies self.javaPackage.ownedMember -> select(m| m.oclIsTypeOf(JavaClass))
-> forAll (c| c.oclAsType(JavaClass).superClass <> self)
[6] The access level protected, private or static can only be applied to nested classes, i.e., that are declared
within the declaration of another class. (self.visibility = #protected or self.visibility = #private or
self.isStatic) implies self.javaPackage.ownedMember -> select(m| m.oclIsTypeOf(JavaClass))
-> exists (c | c.oclAsType(JavaClass).nestedClass -> includes(self))
[7] Private methods of a class cannot be declared abstract. self.javaOperation -> select(op|
op.oclIsTypeOf(Method)) -> forAll (m | m.visibility = #private implies not m.oclAsType(Method).
isAbstract)
[8] Static methods of a class cannot be declared abstract. self.javaOperation -> select(op|
op.oclIsTypeOf(Method)) -> forAll (m | m.isStatic implies not m.oclAsType(Method).
isAbstract)
[9] Final methods of a class cannot be declared abstract. self.javaOperation -> select(op|
op.oclIsTypeOf(Method)) -> forAll (m | m.oclAsType(Method).isFinal implies not
m.oclAsType(Method).isAbstract)
[10] A class is generic if it has a signature template. isGeneric = (self.ownedTemplateSignature -> size
() =1)
[11] Parameters is derived from the parameters of the signature template. /parameters= self.ownedTemplateSignature.parameter
[12] A class is concrete, if its methods have associated an implementation. not self.isAbstract implies
self.allMethod () -> forAll (m | self.allBody() -> exist (b| b.signature = m))
[13] Elements, that can be actual parameters of a formal parameter, are of type Java. self.parameters.
parameteredElement -> forAll (p| p.oclIsTypeOf (JavaType))
Additional Operations
[1] allMethod is the set of all methods, i.e., the methods that are own, inherited and, the methods of
the interfaces implemented. allMethod (): Set(Method) allMethod () = self.allClassMethod() ->
union(self.implement.allInterfaceMethod ()) allClassMethod (): Set (Method) allClassMethod
() = self.javaOperation -> select(o |o.oclIsType(Method)) -> union(self.superClass.allClassMethod()) allInterfaceMethod (): Set(Method) allInterfaceMethod () = self.method -> union(self.
superInterface.allInterfaceMethod ())
[2] allBody is the set of all method implementations of a class, i.e., both own and inherited. allBody():
Set (Implementation) allBody = self.allMethod ().body
44
45
operations<localOperationsList>
}
The parameters are a source and a target metamodel that are instances of Metamodel_A and
Metamodel_B. The section local operations includes a set of operations that are used many times in
this transformation. Preconditions state relations between the metaclasses of the source metamodel.
Postconditions deal with the state of models after transformation.
Below, we show a part a transformation of a PIM to a PSM based in the Eiffel platform. It refers to
concrete instances of metamodels and transformations and links between them. Links connect an instance
of a transformation with an instance of a metamodel.
Postconditions specify how classes and interfaces of the source model are related with classes in the
target model, guaranteeing, for instance, that for each class in the source exists a class in the target so
that: the source class and the target class have the same name, visibility, abstraction degree, restrictions
and parameters (if any), attributes and operations both in, the source and target, must match and so on
Transformation PIM-UML to PSM-EIFFEL {parameters
sourceModel: PIM-Metamodel:: Package
targetModel: PSM-EIFFEL-Metamodel:: Package
preconditions--postconditions-- sourceModel and targetModel have the
same number of classifiers.
targetModel.ownedMember -> select(oclIsTypeOf (EiffelClass)) ->
size() =
sourceModel.ownedMember -> select(oclIsTypeOf(Class) -> size () +
sourceModel.ownedMember -> select(oclIsTypeOf(Interface)) -> size ()
-- for each sourceInterface in sourceModel exists a targetClass
in targetModel so that:
sourceModel.ownedMember -> select(oclIsTypeOf(Interface))->
forAll (sourceInterface| targetModelownedMember -> select (oclIsTypeOf (EiffelClass)) ->
exists (targetClass|
-- targetClass matches sourceInterface.
targetClass.oclAsType (EiffelClass).
classInterfaceMatch (sourceInterface.oclAsType (interface))))
-- for each class sourceClass in sourceModel exists a
targetClassin targetModel so that:
sourceModel.ownedMember -> select (oclIsTypeOf (Class)) ->
forAll (sourceClass targetModel.ownedMember -> select(oclIsTypeOf
(EiffelClass)) ->
exists (targetClass |
-- targetClass matches sourceClass.
targetClass.oclAsType (EiffelClass).classClassMatch (sourceClass.
oclAsType(Class))))
local operationsPSM-EIFFEL-Metamodel::EiffelClass::
46
reFerenceS
Meyer, B. (1992). Eiffel: The Language. Prentice Hall.
Meyer, B. (1997). Object-Oriented software Construction. Prentice Hall.
MOF. (2006). MOF: Meta Object facility (MOF ) 2.0. OMG Specification formal/2006-01-01. Retrieved on July 20, 2009 from www.omg.org/mof
OCL. (2006). OCL: Object Constraint Language. Version 2.0. OMG: formal/06-05-01.Retrieved on
July 20, 2009 from www.omg.org
QVT. (2008). QVT: MOF 2.0 Query, View, Transformation. Formal/2008-04-03. Retrieved on July 20,
2009 from www.omg.org
47
Section 2
Formalization of MOF-Based
Processes
49
Chapter 4
Formalization of
MOF-Based Metamodels
intrOductiOn
Formal and semiformal techniques can play complementary roles in MDA-based software development
processes. We consider it beneficial for both semiformal and formal specification techniques. On the one
hand, semiformal techniques lack a precise semantics; however, they have the ability to visualize language
constructions, allowing a great difference in the productivity of the specification process, especially
when the graphical view is supported by means of good tools. On the other hand, formal specification
allows us to produce a precise and analyzable software specification and clarifies the intended meaning
of metamodels, helps to validate model transformations, and provides reference for implementations;
however, they require familiarity with formal notations that most designers and implementers do not currently have and the learning curve for the application of these techniques requires considerable time.
A combination of metamodeling and formal specification techniques can help us to address MDAbased processes such as reverse engineering, forward engineering and round-trip engineering. In light of
this, we propose to use the algebraic metamodeling language, called NEREUS which can be viewed as
an intermediate notation. NEREUS can be integrated with different formal languages and object-oriented
languages. It is particularly suited for specifying metamodels based on the concepts of entity, relation
and system. Most of the MOF metamodel concepts can be mapped directly to NEREUS.
In terms of NEREUS we will explain a reusable infrastructure for more efficient development of
evolution system techniques and high quality of the results. In the following sections we summarize
the main specification languages linked to object-orientation approaches such as UML and MDA and,
motivate the use of NEREUS as a metamodeling language.
DOI: 10.4018/978-1-61520-649-0.ch004
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
50
Gogolla and Henderson-Seller (2002) analyze the UML metamodel part dealing with stereotypes,
and make various suggestions for improving the definition and use of stereotypes. Barbier, HendersonSellers, Le Parc-Lacayrelle and Bruel (2003) introduce a formal definition for the semantics of the
Whole-Part relation that had been incorporated into version 2.0 of UML. Kuske, Gogolla, Kollmann
and Kreowski (2002) describe an integrated semantics for UML class, object and state diagrams based
on graph transformation.
Graph transformation theory has been developed over the last three decades as a suite of techniques
and tools for formal modeling and very high-level visual programming (Rozenberg, 1997). AGG is a
rule-based visual programming environment supporting an algebraic approach to graph transformation
that is used for modeling and software validation (Taentzer, 2004).
UML CASE tools could be enhanced with functionality for formal specification, deductive verification;
however, only research tools provide support for advanced analysis. For example, the main task of USE
tool (Gogolla, Bohling and Ritchers, 2005) is to validate and verify specifications consisting of UML/
OCL class diagrams. Key (Ahrendt et al., 2005) is a tool based on Together enhanced with functionality
for formal specification and deductive verification (CASE, 2009) (Ahrent, Baar, Beckert, Bubel, Giese,
Hahnle, Menzel, Mostowski, Roth, Schlager, & Smith, 2005) (Ahrent, Baar, Beckert, Giese, Hahnle,
Menzel, Mostowski, & Smith, 2005).
It is difficult to compare the existing results and to see how to integrate them in order to define a
standard semantics since they specify different UML subsets and they are based on different formalisms.
For instance, the books (Siau, & Halpin, 2001) and (Favre, 2003) describe different approaches.
With the emergence of MDA, the emphasis moved from UML formalization to MOF-based metamodel formalization.
MCumber and Cheng (2001) propose a general framework for formalizing UML diagrams in terms
of different formal languages using a mapping from UML metamodels and formal languages.
Akehurst, Kent and Patrascoiu (2003) describe how to formalize metamodels and model transformations by using relational algebras. They propose an approach that uses metamodeling patterns capturing the essence of mathematical relations. The proposed technique is to adopt a pattern that models a
transformation relationship as a relation or collections of relations, and encode this as an object model.
Hausmann (2003) defined an extension of a metamodeling language to specify mappings between metamodels based on concepts presented in Akehurst, Kent and Patrascoiu (2003). Kuster, Sendall and Wahler
(2004) compare and contrast two approaches to model transformations: one is graph transformation and
the other is a relational approach. Buttner and Gogolla (2004) analyze UML metamodel transformations
using a specific graph transformation tool, AGG. Czarnecki and Helsen (2003) describe taxonomy with
a feature model to compare several existing and proposed model-to-model transformation approaches.
To date, there is no way to integrate semantically formal languages and their related tools with
Model-Driven Development.
Poernomo (2004) proposes a formalization of MOF metamodels within the constructive type theory.
Joualt & Kurtev (2006) describe ATL that is a transformation language that implements the MOFmetamodel Query, View, Transformation (QVT).
More recently, (Boronat, & Meseguer, 2007) and (Boronat, & Messeger, 2008) present a formal, algebraic semantics of the MOF standard in membership equational logic (MEL). An executable framework
for MOF has been integrated within the Eclipse Modeling framework (Eclipse, 2009).
51
Mda inFraStructure
Our goal is to formalize MDA processes in terms of MOF-based metamodels and QVT-based transformations. Both, MOF and QVT, depend on UML metamodel, which in turn depends on OCL. That is to
say, the formalization of MDA processes depends on various OMG standards. Some of them, such as
OCL and QVT, involve imperative constructions that are hard to formalize. To avoid this inconvenient,
we analyzed the graph of package dependencies to select a minimal set of packages that allows us to
precisely define the semantics of MDA process in a way independent of imperative constructions. Next,
we describe the package dependencies involve in this analysis.
The Infrastructure::Core package is a complete metamodel that is reused by other metamodels that
import or specialize its metaclasses.
MOF 2.0 reuses and integrates the UML Infrastructure::Core and provides two metamodels EMOF
(Essential MOF) and CMOF (Complete MOF). EMOF favors simplicity of implementation over expressiveness. CMOF is the metamodel used to specify more sophisticated metamodels such as UML 2.2
Superstructure. It is built from EMOF and the Core::Constructs of UML 2.2 (see Chapter 2 Figure 9).
MOF, like all metamodels in the MOF and UML family, is described as a CMOF model. However,
EMOF can be described in itself. This results in a complete, standalone model of EMOF that has no
dependencies on any other packages, or metamodeling capabilities that are not supported by EMOF
itself.
Other important consideration is that MOF and QVT depends only on UML Core::Basic package
which at the same time only depends on EssentialOCL, a subset of the complete OCL, exposing the
minimal OCL required to work with EMOF (see Chapter 2 Figures 9 and 11). It references explicitly the
EMOF classes: Property, Operation, Parameter, TypedElement, Type, Class, DataType, Enumeration,
PrimitiveType, and EnumerationLiteral. The following metaclasses defined in complete OCL are not
part of EssentialOCL: MessageType, ElementType, AssociationClassCallExp, MessageExp, StateExp,
UnspecifiedValueExp. Moreover, any well-formedness rules defined for these classes are consequently
not part of the definition of Essential OCL. Then, EssentialOCL does not depend on imperative constructions (OCL, 2006).
On the other hand, QVT has a hybrid declarative/imperative nature. The declarative part includes two
metamodels/languages layers: Relation and Core. The latter is defined using Essential OCL and EMOF.
The Core language is equally powerful to the Relation language and can be implemented directly or
used as a reference for defining the semantics of relations, which are mapped to Core using the transformation language itself (see Chapter 2 Figure 11). Then, we can formalize QVT transformations via
the formalization of the QVT::Core and QVT::Base. We can reason about transformations by reasoning
about the corresponding core transformation.
Considering the above, we select a minimal subset of packages of OMG standards to formalize MDA
process. This subset constitutes an MDA Infrastructure that can be reused by different MDA processes.
Figure 1 shows the components of the MDA Infrastructure.
To formalize metamodels, we use a special-purpose language NEREUS. It takes advantage of all the
existing theoretical background on formal methods, for instance, the notions of refinement, implementation correctness, observable equivalences and behavioral equivalences that play an essential role in
model-to-model transformations (Astesiano, Kreowski, & Krieg-Bruckner, 1999) (Cardelli, & Wegner,
1985). The system type of NEREUS was defined rigorously in the algebraic framework. Considering
that MOF supports only binary associations, NEREUS typifies a hierarchy of type constructor for binary
52
associations and provides rigorous specification of them. The semantics of MOF metamodels (that is
specified in OCL) can be enriched and refined by integrating it with NEREUS. This integration facilitates
proofs and tests of models and model transformations via the formal specification of metamodels and
metamodel transformations. Some properties can be deduced from the formal specification and could
be re-injected into the MOF specification without wasting the advantages of semi-formal languages of
being more intuitive and pragmatic for most implementers and practitioners.
In contrast to the works mentioned above, our approach has two main advantages linked to automation and interoperability. On the one hand, we show how to generate automatically formal specifications
from MOF metamodels. Due to scalability problems, this is an essential requisite. We define a system of
transformation rules for translating MOF metamodels specified in OCL into algebraic languages. On the
other hand, our approach focuses on interoperability of formal languages. Languages that are defined in
terms of NEREUS metamodels can be related to each other because they are defined in the same way
through a textual syntax. Any number of source languages such as different Domain Specific Languages
(DSLs) and target languages (different formal language) could be connected without having to define
explicit metamodel transformations for each language pair (Figure 2). Such as MOF is a DSL to define
semi-formal metamodels, NEREUS can be viewed as a DSL for defining formal metamodels.
Another advantage of our approach is linked to pragmatic aspects. NEREUS is a formal notation
closed to MOF metamodels that allows meta-designers who must manipulate metamodels to understand
their formal specification.
Rather than requiring developers to manipulate formal specifications, the idea is to provide rigorous
foundations for MDD in order to develop tools that, on the one hand, take advantage of the power of
formal languages and, on the other hand, allow developers to directly manipulate MDA models; however
meta-designers need to understand MOF metamodels and NEREUS specifications.
Experiments and tool support related to the NEREUS approach may be found at (Favre, 2001) (Favre,
2005) (Favre, 2006) and (Favre, 2009). However, we would like remark that here NEREUS is used as an
intermediate formal notation to communicate the essential of an MDA reverse engineering approach.
53
classes
Classes may declare types, operations and, axioms that are formulas of first-order logic. They are structured by three different kinds of relations: importing, inheritance and subtyping. The syntax of a class
is as follows:
CLASS className
IMPORTS<importList>IS-SUBTYPE-OF<subtypeList>INHERITS<inheritList>GE
NERATED-BY<constructorList>
DEFERRED
TYPES<sortList>ATTRIBUTES<attributeList>OPERATIONS<operationList>
EFFECTIVE
TYPES<sortList>ATTRIBUTES<attributeList>OPERATIONS<operationList>AXI
OMS<varList> <axiomList>
END-CLASS
The clauses IMPORT, INHERITS, IS-SUBTYPE-OF, DEFERRED and EFFECTIVE are optional
and there is no order between them, except the lineal order imposed by the visibility: each symbol has
to be declared before being used.
Types, attributes and operations can be declared as DEFERRED or EFFECTIVE. The DEFERRED
clause declares elements that are incompletely defined due to there are not enough axioms to define the
behavior of the new operations or, there are not enough operations to generate all values of a sort. The
EFFECTIVE clause either declares new types, operations or attributes that are completely defined or
completes the definition of some inherited type, attribute or operation.
54
55
axioms
The AXIOMS clause declares pairs v: C where v is a universal quantified variable of type C. Following this clause, axioms are included to specify the class semantics. As for many-sorted specifications,
axioms are formulas in first-order logic.
A term is a typed variable, a constant or a well-formed operation application. Formulas may be
atomic or compound. An atomic formula is an equivalence equation between two terms of the same
type. Equations of the form term=True can be abbreviated by term. All operations are strict, if one of
its arguments is undefined, the result too. A compound formula (or predicate) is built by using the logic
operators not, and, implies and equivalence.
To facilitate the use of conditionals, the class Boolean provides the operation IF-THEN-ELSE whose
signature is:
IF-THEN-ELSE: Boolean x S x S -> S
and the axioms related are:
IF-THEN-ELSE (True, x, y) = x
IF-THEN-ELSE (False, x, y) = y
2PARAMETERIZED CLASSES
NEREUS distinguishes variable parts in a specification by means of explicit parameterization. The
elements of <parameterList> are pairs C1:C2 where C1 is the formal generic parameter constrained by
an existing class C2 (only subclasses of C2 will be actual parameters). The syntax of a parameterized
class is as follows:
CLASS className [<parameterList>]IMPORTS<importList>IS-SUBTYPE-OF<su
btypeList>INHERITS<inheritList>GENERATED-BY<constructorList>
DEFERRED
TYPES<sortList>FUNCTIONS<functionList>
EFFECTIVE
TYPES<sortList>FUNCTIONS<functionList>AXIOMS<varList>
<axiomList>
END-CLASS
56
association definition
NEREUS provides a taxonomy of constructor types that classifies binary association according to kind
(ordinary association, aggregation and composition), degree (unary, binary), navigability (unidirectional,
bidirectional), and connectivity (e.g. one-to-one, one-to-many and many-to-many). Figure 3 partially
depicts the hierarchy of constructor types.
Generic relations can be used in the definition of concrete relations by instantiation. New associations can be defined as follows:
ASSOCIATION <relationName>
IS <constructorTypeName> [:class1;:class2;:role1;:role2;
:mult1;:mult2;:visibility1;:visibility2]
CONSTRAINED-BY <constraintList>
END
58
The IS paragraph expresses the instantiation of <constructorTypeName> with classes, roles, visibility
and multiplicity. The CONSTRAINED-BY clause allows the specification of predefined constraints
(ordered, changeable, addOnly, Frozen, xor, subset) and specific static constraints in first-order logic.
Associations are defined in a class by means of the ASSOCIATES clause:
CLASS className
ASSOCIATES <<associationName>>
END-CLASS
Package definition
The package is the mechanism provided by NEREUS for grouping classes and associations and controlling its visibility. The syntax of a package is as follows:
PACKAGE packageName
IMPORTING <importsList>
GENERALIZATION <inheritsList>
NESTING <nestingList>
CLUSTERING <clusteringList>
<elements>
END-PACKAGE
Like MOF, NEREUS provides mechanisms for metamodel composition and reuse (importing, generalization, nesting and clustering) (MOF, 2002, pp. 2-14) The IMPORTING clause lists the imported
packages (<importsList>); the GENERALIZATION clause lists the inherited packages in <inheritList>;
NESTING clause lists the nested packages (<nestingList>) and CLUSTERING clause lists the clustering ones (<clusteringList>).
comments
A comment is a line preceded by - -
-- <texto>
the :: notation
The :: notation allows expressing the name of an element as an ordered list of another elements in
which it is contained. The syntax for using it is:
Package::Class::roleName
Next, we show examples of NEREUS specifications.
59
collection in OcL
size (): Integer
The number of elements in the collection self.
post: result = self -> iterate (elem; acc: Integer = 0 | acc + 1)
includes (object: T): Boolean
True if object is an element of self, false otherwise.
post: result = (self -> count (object) > 0)
excludes (object: T): Boolean
True if object is not an element of self, false otherwise.
post: result = (self -> count (object) = 0)
count (object: T): Integer
The number of times that object occurs in the collection self.
post: result = self -> iterate (elem; acc: Integer = 0 | if elem =
object then acc + 1 else acc endif)
includesAll (c2: Collection (T)): Boolean
Does self contain all the elements of c2 ?
post: result = c2 -> forAll (elem | self -> includes (elem))
excludesAll (c2: Collection (T)): Boolean
Does self contain none of the elements of c2 ?
post: result = c2 -> forAll(elem | self -> excludes (elem))
isEmpty(): Boolean
Is self the empty collection?
post: result = (self -> size () = 0)
60
collection in nereuS
Following we show the predefined type OCL-Collection in NEREUS (Favre, 2001). Collection is a parameterized class. It imports Boolean and Nat specifications. Its basic constructor operations are create
and add. The sort Collection and the operations create, add, count and collect are defined as deferred.
For instance, the count operation determines the number of times that an element occurs in the Collection. Due to the collection Set does not admit more than one occurrence, the semantics of count can only
be completed in the subclasses. The rest of its operations are effective. Some of them are second-order
operations (forAll, select, exists and iterate). The semantic specification of count exemplifies how to
use local definitions by using the WHERE paragraph. The includes and excludes operations exemplify
the use of the if-then-else notation.
CLASS Collection [Elem]
IMPORTS Boolean, Nat
GENERATED-BY create, add DEFERREDTYPES
Collection
OPERATIONS
create: Collection
add: Collection x Elem Collection
count: Collection x Elem Nat
collect: Collection x (Elem -> Elem1: ANY) -> Collection
EFFECTIVEOPERATIONS
isEmpty: Collection -> Boolean
61
Set in OcL
union (s: Set (T)): Set (T)
The union of self and s.
post: result -> forAll (elem | self -> includes (elem) or s -> includes (elem))
post: self -> forAll (elem | result -> includes(elem))
post: s -> forAll (elem | result -> includes (elem))
union(bag: Bag(T)): Bag(T)
The union of self and bag.
post: result -> forAll (elem |
result -> count (elem) = self -> count (elem) + bag -> count (elem))
post: self -> forAll (elem | result -> includes (elem))
post: bag -> forAll (elem | result -> includes (elem))
= (s: Set (T)): Boolean
Evaluates to true if self and s contain the same elements.
post: result = (self -> forAll (elem |
s -> includes (elem)) and s -> forAll (elem | self -> includes
(elem)))
intersection (s: Set (T)): Set (T)
The intersection of self and s
are in both self and s).
post: result -> forAll (elem |
cludes (elem))
post: self -> forAll (elem | s
cludes (elem))
post: s -> forAll (elem | self
cludes (elem))
63
64
Set in nereuS
The class Set is a subtype of Collection. The IS-SUBTYPE-OF clause exemplifies the definition of
a local instance of Collection that renames the operations create and add by createSet and including
respectively. All operations are defined as effective. In AXIOMS, a concise notation for second-order
operations is exemplified. For instance, forAll(v) (s, [includes (union (s, s2), v)]) refers to an operation
forAll over an index v, and collection s and the logical expression includes (union (s, s2), v).
CLASS Set [T]
IS-SUBTYPE-OF Collection [T] [create: createSet; add: including]
IMPORTS Sequence, Bag [create: createBag; including: includingBag],
OrderedSet EFFECTIVETYPES
Set
OPERATIONS
createSet, including, count
equal: Set x Set > Boolean
union: Set x Set Set
65
67
69
70
72
IS-SUBTYPE-OFUML::Classes::Kernel::Namespace
ASSOCIATES
<< State-Region>>
<< StateMachine-Region>>
<< Region-Vertex >>
AXIOMS a: Region-Vertex; r: Region
size (select (p) (select (v) (get_subvertex (a, r),
oclIsKinfOf (v, PseudoState) ]), [kind(p) = #initial])) <= 1
END-CLASSCLASS PseudoState
IS-SUBTYPE-OF Vertex, NameElement
ASSOCIATES
<<Vertex-Transition-1>>
<<Vertex-Transition-2>>
<< StateMachine-PseudoState>>
OPERATIONS
kind: PseudoState -> PseudoStateKind
AXIOMS ps: PseudoState; a: Vertex-Transition-1
kind (ps) = #initial implies
size (get_outgoing (a,ps)) <=1
END-CLASSASSOCIATION stateMachine-PseudoState
IS Composition-2 [StateMachine: class1; PseudoState: class2;
stateMachine: role1; conectionPoint: role2; 0..1: mult1; *: mult2;
+: visibility1;+: visibility2]
CONSTRAINED-BY StateMachine: subsets namespace; PseudoState: subsets
ownedMember
ENDASSOCIATION Region-Vertex
IS Composition-2 [Region: class1; Vertex: class2; container: role1;
subvertex: role2; 0..1: mult1; *: mult2; +: visibility1; +: visibility2]
CONSTRAINED-BY Region: subsets namespace; Vertex: subsets ownedMember
END
END-PACKAGE
73
lowing constraints (extendingRule and transitiveRule) may be attached to the package specifying that
the rules of the extended transformation are included in the extending transformation and the extension
is transitive:
extendingRule =
Transformation.allInstances -> forAll (t|
t.extends.size = 1 implies t.extends.rule -> include (t.rule))
transitiveRule =
Transformation.allInstances ->
forAll (t1, t2, t3 | t1.extends.size = 1 and t2.extends.size = 1 and
t3.extends.size = 1
and (t1.extends.rule -> includes (t2.rule) and
t2.extends.rule -> includes (t3.rules)) implies t1.extends.rule ->
includes (t3.rule)
A rule domain is the set of model elements of a typed model that are of interest to it. A domain may
be marked as checkable or enforceable
An analogy between a virtual machine-based architecture and QVT is described in (QVT, 2008 pp.
10). The Core language is like JAVA byte code and the Core semantics is like the behavior specification
for the Java Virtual Machine (JVM). The Relation language is like the Java language, and the standard
transformation from Relations to Core is like the Java compiler which produces byte code. We can go
beyond that showing an analogy between the semantics of the JVM byte code and the core of QVT.
The semantics of Java, that includes object-oriented features, is hard to formalize. However, JVM byte
code is defined more precisely. Liu and Moore (2004) proved that Java program verification via a deep
embedding of the JVM into the logic of ACL2 (Kaufman & Moore, 2009) is a viable approach. Analogously, the semantics of QVT, that includes mechanisms for involving imperative implementations of
transformations, is hard to formalize. The Core package that is based on QVT Base package, EMOF and
Essential OCL (see Chapter 2 Figure 11) is more simply and more precisely defined. Then, we decided
to formalize QVT transformations via the QVT core and QVT base formalization.
74
We can reason about transformations by reasoning about the corresponding core transformation.
Following, we include a partial specification in NEREUS of the QVT-BASE package.
As an example, the OCL specification, extendingRule and transformationRule can be translated into
the shaded axioms.
PACKAGE QVTBase
CLASS Transformation
IMPORTS EMOF::Tag
INHERITS EMOF::MetaClass, EMOF::Package
ASSOCIATES
<<Transformation-Tag>>
<<Transformation-Transformation>>
<<Transformation-Rule>>,
<<Transformation-TypeModel>>
AXIOMS ass1: <<Transformation-Transformation>>;
ass2: <<Transformation-Rule>> ; t: Transformation ;
size (get_extends (ass1, t)) = 1 implies
includes (get_rule (ass2, get_extends (ass1, t)), get_rule (ass1,
t))
END-CLASSCLASS TypedModel
IMPORTS EMOF::Package
IS-SUBTYPE-OF EMOF::NamedElement
ASSOCIATES
<<Transformation-TypeModel>>
<<TypeModel-Package>>
<<Domain-TypeModel>>
<<TypeModel-TypeModel>>
END-CLASSCLASS Domain
IS-SUBTYPE-OF EMOF::NamedElement
ASSOCIATES
<<Rule-Domain>>
<<Domain-TypeModel>>
DEFERREDATTRIBUTES
isCheckable: Domain -> Boolean
isEnforceable: Domain -> Boolean
END-CLASSCLASS Rule
IS-SUBTYPE-OF EMOF::NamedElement
ASSOCIATES
<<Rule-Domain>>
<<Rule-Rule>>
<<Transformation-Rule>>
END-CLASSASSOCIATION Transformation-Transformation
IS Unidirectional-2 [Transformation: class1; Transformation: class2;
extendedBy: role1; extends: role2; *: mult1; 0..1: mult2; +: visibility1; +: visibility2]
75
END-ASSOCIATIONASSOCIATION Transformation-Rule
IS Composition-2 [Transformation: class1; Rule: class2; transformation: role1; rule: role2; 1: mult1; *: mult2; +: visibility1; +:
visibility2]
END-ASSOCIATIONASSOCIATION Transformation-TypedModel
END-PACKAGE
reFerenceS
Abrial, J. (1996). The B Book: Assigning Programs to Meanings. Cambridge: Cambridge University
Press.
Ahrendt, W., Baar, T., Beckert, B., Bubel, R., Giese, M., & Hhnle, R. (2005). The Key Tool. Software and
Systems Modeling, 4, 3254. doi:10.1007/s10270-004-0058-x
Akehurst, D., Kent, S., & Patrascoiu, O. (2003). A relational approach to defining and implementing
transformations between metamodels. Software and System Modeling, 2(4), 215239. doi:10.1007/s10270003-0032-z
Alencar, A., & Goguen, J. (1991). OOZE: An Object-oriented Z Environment. In Proceedings of the European Conference on Object-oriented Programming, ECOOP 91 (LNCS 512, pp. 180-199. Heidelberg:
Springer-Verlag.
Astesiano, E., Kreowski, H., & Krieg-Bruckner, B. (Eds.). (1999). Algebraic Foundations of System Specification. Heidelberg: Springer-Verlag.
Barbier, F., Henderson-Sellers, B., Le Parc-Lacayrelle, A., & Bruel, J. (2003). Formalization of the WholePart Relationship in the Unified Modeling Language. IEEE Transactions on Software Engineering, 29(5),
450470. doi:10.1109/TSE.2003.1199074
Bidoit, M., & Mosses, P. (2004). CASL User Manual- Introduction to Using the Common Algebraic Specification Language (LNCS 2900). Heidelberg: Springer-Verlag.
Bordeau, R., & Cheng, B. (1995). A Formal Semantic for Object Model Diagrams. IEEE Transactions on
Software Engineering, 21(10).
Borger, E., Cavarra, A., & Riccobene, E. (2000). An ASM Semantics for UML Activity Diagrams. In T.
Rus (Ed.), Proceedings AMAST 2000 (LNCS 1816, pp. 293-308). Heidelberg: Springer-Verlag.
Boronat, A., & Meseguer, J. (2007). Algebraic semantics of EMOF/OCL metamodels (Technical Report
UIUCDCS-R-2007-2904, CS Dept., University of Illinois at Urbana-Champaign). Retrieved on July 20,
2009 from https://www.ideals.uiuc.edu/handle/2142/11398
Boronat, A., & Messeger, J. (2008). An algebraic semantics for MOF. In J. Fiadiero & P. Inverardi (Eds.),
FASE 2008 (LNCS 4961, pp. 377- 391). Heilderberg: Springer-Verlag.
Bruel, J., & France, R. (1998). Transforming UML Models to Formal Specifications. CiteSearX. Retrieved
on July, 20 from http://www.oblog.pt/Download/P7.ps
76
Bttner, F., & Gogolla, M. (2004). Realizing UML Metamodel Transformations with AGG. In: R. Heckel
(Ed.). In Proceedings of ETAPS Workshop Graph Transformation and Visual Modeling Techniques (GTVMT 2004). Retrieved on July 20, 2009 from wwwcs.uni-paderborn.de/cs/ag-engels/GT-VMT04.
Cardelli, L., & Wegner, P. (1985). On understanding Types, Data Abstraction and Polymorphism. ACM
Computing Surveys, 17(4), 471522. doi:10.1145/6041.6042
CASE. (2009). CASE Tools. Retrieved on July 20, 2009 from www.objectsbydesign.com/tools/umltools_byCompany.html
CWM. (2003).Common Warehouse Metamodel, v. 1.1 formal/2003-03-02. Retrieved on July 20, 2009
from www.omg.org/spec/cwm
Czarnecki, K., & Helsen, S. (2003). Classification of Model Transformation Approaches. In J. Bettin et
al. (Eds), Proceedings of OOSPLA 2003 Workshop on Generative Techniques in the Context of ModelDriven Architecture. Retrieved on July 20, 2009 from www.swen.uwaterloo.ca/~kczarnec/ECE750T7/
czarnecki_helsen.pdf
Eclipse (2009). The eclipse modeling framework. Retrieved from July 20, 2009 from http://www.eclipse.
org/emf/
Favre, L. (2001). A Formal Mapping between UML Static Models and Algebraic Specifications. Lecture
Notes in Informatics (p. 7) Evans, A. France, R., Moreira, A., & Rumpe, B.(Eds) SEW Practical UMLBased Rigorous Development Methods- Countering or Integrating the eXtremists. (pp. 113 - 127) Bonn:
GI Edition, Bonner Kollen-Verlag.
Favre, L. (Ed.). (2003). UML and the Unified Process. Hershey, PA: IRM Press.
Favre, L. (2005). Foundations for MDA-based Forward Engineering. Journal of Object Technology (JOT),
4(1), 129-153). Retrieved on July 20, 2009 from www.jot.fm
Favre, L. (2006). A Rigorous Framework for Model Driven Development. In K. Siau (Ed.), Advanced
Topics in Database Research, Vol. 5 (pp. 1-27). Hershey, PA: Idea Group Publishing.
Favre, L. (2009) A Formal Foundation for Metamodeling (LNCS 5570, pp. 177-191). Heilderberg: SpringerVerlag. France, R., Bruel, J., & Larrondo-Petrie, M. (1997). An Integrated Object-Oriented and Formal
Modeling Environment. JOOP, November-December.
France, R., Evans, A., Lano, K., & Rumpe, B. (1998). The UML as a Formal Modeling Notation. Computer
Standards & Interfaces, 19(7), 325334. doi:10.1016/S0920-5489(98)00020-8
France, R., Bruel, J., & Larrondo-Petrie, M. (1997). An Integrated Object-Oriented and Formal Modeling
Environment, JOOP, November-December.
Gerber, A., Lawley, M., & Raymond, K. Steel, J., & Wood, A. (2002) Transformation: The Missing Link
of MDA. In Proceedings of Graph Transformation- First International Conference, ICCT 2002 (LNCS
2505, pp. 90-105). Heidelberg: Springer-Verlag.
Gogolla, M., Bohling, J., & Richters, M. (2005). Validating UML and OCL Models in USE by Automatic
Snapshot Generation. Journal on Software and System Modeling, 4(4), 386398. doi:10.1007/s10270005-0089-y
77
Gogolla, M., & Henderson-Sellers, B. (2002). Formal Analysis of UML Stereotypes within the UML
Metamodel. In Proceedings of <<UML>> 2002, 5th Int.Conf. Unified Modeling Language (LNCS 2460,
pp. 84-92). Heidelberg: Springer-Verlag
Gogolla, M., & Richters, M. (1998). On Constraints and Queries in UML. The Unified Modeling Language Technical Aspects and Applications, Physica-Verlag. Retrieved on July 20, 2009 from http://www.
db.informatik.uni-bremen.de/publications/Gogolla_1997_UMLWS.ps
Haussmann, J. (2003). Relations-Relating metamodels. In A. Evans, P. Sammut, & J. Williams (Eds.),
Proceedings of Metamodeling for MDA. First International Workshop York, UK (pp. 147-161).
Joualt, F., & Kurtev, I. (2006). On the Architectural Alignment of ATL and QVT. In Proceedings of 2006
ACM Symposium on Applied Computing (SAC 2006) Chapter Model Transformation (pp. 1188- 1195).
ACM.
Kaufman, M., & Moore, J. S. (2009). ACL2 version 3.5. Retrieved on July 20, 2009 from http://www.
cs.utexas.edu/~moore/acl2/
Kim, S., & Carrington, D. (1999). Formalizing the UML Class Diagram using OBJECT-Z. In Proceedings
of UML 99 (LNCS 1723, pp. 83-98). Heidelberg: Springer-Verlag.
Kim, S., & Carrington, D. (2002). A Formal Model of the UML Metamodel: The UML State Machine and
Its Integrity Constraints (LNCS 2272, pp. 477- 496). Heidelberg: Springer-Verlag.
Kuske, S., Gogolla, M., Kollmann, R., & Kreowski, H. (2002). An Integrated Semantics for UML Class,
Object and State Diagrams based on Graph Transformation. In Proceedings 3rd Int. Conf. Integrated
Formal Methods (IFM 02). Heidelberg: Springer-Verlag.
Kuster, J., Sendall, S., & Wahler, M. (2004). Comparing Two Model Transformation Approaches. In J.
Bezivin et al (Eds.), Proceedings of OCL and Model Driven Engineering Workshop. Lisboa, Portugal.
Retrieved on July 20, 2009 from http://www.cs.kent.ac.uk/projects/ocl/oclmdewsuml04/
Lano, K. (1991). Z++, An Object-Oriented Extension to Z. Z User Workshop (pp. 151-172). Heidelberg:
Springer.
Leavens, G. (1996). An Overview of Larch/C++: Behavioral Specification for C++ Modules. Specification of Behavioral Semantics in Object-Oriented Information Modeling (pp. 121-142). Kluwer Academic
Publishers.
Leavens, G., Poll, E., Clifton, C., Cheon, Y., & Ruby, C. (2002). JML Reference. Manual Draft Revision
1.1. Retrieved on July 20, 2009 from www.cs.iastate.edu/~leavens
Liu, H., & Strother Moore, J. (2004). Java Program verification via JVM Deep Embedding in ACL2.
Lecture Notes in Computer Science 3223 (pp.184 - 200). Heildelberg: Springer-Verlag.
McUmber, W., & Cheng, B. (2001). A General Framework for Formalizing UML with Formal Languages.
In Proceedings of the IEEE International Conference on Software Engineering (ICSE01).
Mens, T., Van Gorp, P., Varr, D., & Karsai, G. (2006). Applying a Model Transformation Taxonomy to
Graph Transformation Technology. Electronic Notes in Theoretical Computer Science, 152, 143159.
doi:10.1016/j.entcs.2005.10.022
78
MOF. (2002). Meta Object Facility (MOF) Specification version 1.4. Document formal/01-11-02. Retrieved
on July 20, 2009 from www.omg.org
OCL. (2006). OCL: Object Constraint Language. Version 2.0. OMG: formal/06-05-01.Retrieved on July
20, 2009 from www.omg.org
Overgaard, G. (1998). A Formal Approach to Relationships in the Unified Modeling Language. In Proceedings of Workshop on Precise Semantic of Modeling Notations, International Conference on Software
Engineering, ICSE 98, Japan. Retrieved on July 20, 2009 from http://www.it.kth.se/~gunnaro/pub/psmt98.
rev.ps
Paige, R., Kaminskaya, L., & Ostroff, J. (2002). BON-CASE: An Extensible CASE Tool for Formal
Specification and Reasoning. Journal of Object Technology (JOT) 1(3), 77-96. Retrieved on July 20, 2009
from www.jot.fm
Poernomo, I. (2006). The meta-Object facility Typed. In Proceedings of the 2006 ACM Symposium on
Applied Computing (SAC) (pp. 1845-1849). Dijon, France. ACM.
QVT. (2008). QVT: MOF 2.0 Query, View, Transformation. Formal/2008-04-03. Retrieved on July 20,
2009 from www.omg.org
Rapanotti, L., & Socorro, A. (1992). Introducing FOOPS. Report PRG-TR-28-92, Programming Research
Group, Oxford University Computing Laboratory.
Reggio, G., Cerioli, M., & Astesiano, E. (2001). Towards a Rigorous Semantics of UML Supporting its
Multiview Approach. In Proceedings of Fundamental Approaches to Software Engineering (FASE 2001)
(LNCS 2029, pp. 171-186). Heidelberg: Springer-Verlag.
Rozenberg, G. (Ed.). (1997). Handbook of Graph Grammars and Computing by Graph Transformation
(Vol. 1). World Scientific.
Siau, S., & Halpin, T. (Eds.). (2001). Unified Modeling Language: Systems, Analysis, Design and Development Issues. Hershey, PA: Idea Group Publishing.
Smith, G. (2000). The Object-Z Specification Language. Advances in Formal Methods. Kluwer Academic
Publishers.
Snook, C., & Butler, M. (2002). Tool-Supported Use of UML for Constructing B Specifications. Technical Report, Department of Electronics and Computer Science, University of Southampton, United Kingdom.
Taentzer, G. (2004) AGG: A Graph Transformation Environment for Modeling and Validation of Software.
In Proceedings of Applications of Graph Transformations with Industrial relevance (AGTIVE) (LNCS
3062, pp. 446-453). Heidelberg: Springer-Verlag.
79
80
Chapter 5
MOF-Metamodels and
Formal Languages
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
Figure 2 depicts the different ways in which a class A may be related in a MOF metamodel: generalization, dependency, aggregation, composition and binary associations. Figure 2 shows in an only box
several relations, for instance, the class A is associated with the classes D1, D2, ..Dk or is composed by
the classes C1, C2,Ck. It can be transformed in part of a NEREUS specification by instantiating the
following scheme Class_:
CLASS __
IMPORTS F1, F2,.., Fk
INHERITS B1, B2,...Bk
Box_ [...:attr1;...:attri;...:meth1;..:methi,..]
ASSOCIATES <<Aggregation-E1>>
ASSOCIATES <<Aggregation-E2>>
ASSOCIATES <<Composition-C1>>
ASSOCIATES <<Composition-C2>>...
ASSOCIATES <<Association-D1>>
ASSOCIATES <<Association-D2>>
AXIOMSEND-CLASS
Figure 2. MOF relationships
81
END-CLASS
The mapping of attributes requires two operations: an access operation and a modifier. The access
operation takes no arguments and returns the object to which the receiver is mapped to. The modifier
takes no argument and changes the mapping of the receiver to that argument. In NEREUS no standard
convention exists, but frequently we use names such as get_ and set_ for them.
In the instantiation, the underscore _ is followed by the name of the sort of interest.
tranSFOrMatiOn OF aSSOciatiOnS
Association specification is constructed by instantiating the scheme ASSOCIATION_:
ASSOCIATION __IS __[ _:Class1; _: Class2; _: Role1; _: Role2; _:
Mult1; _: Mult2; _: Visibility1; _: Visibility2]
CONSTRAINED BY __END
Besides, the specification of the association is generated by instantiating the respective scheme in
the hierarchy of binary associations (Chapter 4 Figure 3).
83
The following section describes how to integrate OCL with NEREUS by using a system of transformation rules
84
Postconditions and invariants allow us to generate axioms in NEREUS. We define a system of transformation rules that only considers expressions based on Essential OCL. The following metaclasses
defined in complete OCL are not part of the EssentialOCL: MessageType, StateExp, ElementType,
AssociationClassCallExp, MessageExp, and UnspecifiedValueExp. Any well-formed rules defined for
these classes are consequently not part of the definition of the transformation rule system.
The following tables show some rules for translating OCL expressions into NEREUS. Each rule is a
pair of an OCL expression (the shaded expression at the top) and a NEREUS expression. An introduction
to OCL constructs and the transformation rule system may be found at Appendix-C.
The system includes a small set with around fifty rules. It was built by means of an iterative approach through successive refinements. The set of rules was validated by analyzing the different OCL
expression attached to the UML metamodels (UMLa, 2007) (UMLb, 2007), MOF (MOF, 2006) and
QVT (QVT, 2007).
85
context Meeting::isConfirmed ()
post: result = self.checkdate () and self.numConfirmedParticipants
>= 2
context Person::numMeeting (): Nat
post: result = self.meetings -> size
context Person::numConfirmedMeeting (): Nat
post: result = self.meetings -> select (isConfirmed) -> size
context Meeting::isConfirmed (): Bool
post: result = self.checkdate () and self.numConfirmedParticipants
>= 2
context Meeting::duration (): Time
post: result = timeDifference (self.end, self.start)
context Meeting:: checkDate():Bool
post: result = self.participants-> collect(meetings) ->
86
LET
OPERATIONS
f: Element -> Boolean
AXIOMS v: Element
f (v)= Translate NEREUS (boolean-expr-with-v)
IN
operationName (collection, f)
END-LET
Collection -> operationName (v:Element| boolean-expr-with-v)
operationName::= forAll exists
operationName (collection, f)
WHERE
OPERATIONS
f: Element -> Boolean
AXIOMS v: Element
f (v)= Translate NEREUS (boolean-expr-with-v)
END-WHERE
Collection -> operationName (v:Element| boolean-expr-with-v)
operationName::= forAll exists
Shorthand notation
operationName (v) (collection, [f (v)])
Collection -> operationName (v |boolean-expr-with-v)
operationName::= forAll exists
Collection [Element]
OPERATIONS
operationName: Collection x (Element-> Boolean) -> Boolean
AXIOMS
LET
OPERATIONS
f: Element -> Boolean
AXIOMS v: Element
f (v)= Translate NEREUS (boolean-expr-with-v)
IN
operationName (collection, f)
END-LET
Collection -> operationName (v |boolean-expr-with-v)
operationName::= forAll exists
Collection [Element]
operationName (collection, f)
WHERE
OPERATIONS
f: Element -> Boolean
AXIOMS v: Element
f(v)= Translate NEREUS (boolean-expr-with-v)
END-WHERE
Collection -> operationName (v |boolean-expr-with-v)
operationName::= forAll exists
Collection [Element]
Shorthand notation
operationName (v) (collection, [f (v)])
87
Table 6. continued
Collection -> operationName (v |boolean-expr-with-v)
operationName::= forAll exists
Collection [Element]
OPERATIONS
operationName: Collection x (Element-> Boolean) -> Boolean
AXIOMS
LET
OPERATIONS
f: Element -> Boolean
AXIOMS v: Element
f (v)= Translate NEREUS (boolean-expr-with-v)
IN
operationName (collection, f)
END-LET
Collection -> operationName (v |boolean-expr-with-v)
operationName::= forAll exists
Collection [Element]
operationName (collection, f)
WHERE
OPERATIONS
f: Element -> Boolean
AXIOMS v: Element
f(v)= Translate NEREUS (boolean-expr-with-v)
END-WHERE
Collection -> operationName (v |boolean-expr-with-v)
operationName::= forAll exists
Collection [Element]
Shorthand notation
operationName (v) (collection, [f (v)])
Collection -> operationName (v |boolean-expr)
operationName::= forAll exists
Collection [Element]
OPERATIONS
operationName: Collection x (Element-> Boolean)-> Boolean
AXIOMS
LET
OPERATIONS
f: Element -> Boolean
AXIOMS v: Elem
f(v)= Translate NEREUS (boolean-expr)
IN
operationName (collection, f)
END-LET
Collection -> operationName (v |boolean-expr)
operationName::= forAll exists
Collection [Element]
operationName (collection, f)
WHERE
OPERATIONS
f: Element -> Boolean
AXIOMS v: Elem
f (v)= Translate NEREUS (boolean-expr)
END-WHERE
Collection -> operationName (v |boolean-expr)
operationName::= forAll exists
Collection [Element]
Shorthand notation
operationName (v) (collection, [f (v)])
88
89
Table 7. continued
collection -> iterate (v: Element; acc: Type = exp |
expression-with-v-and-acc)
OPERATIONS
iterate: Collection x (Element x Acc: ANY) x -> Acc) -> Acc
AXIOMS
LET
OPERATIONS
f: Element x Type -> Type
base: -> Type
AXIOMS v: Element; acc: Type
f (v, acc)=TranslateNEREUS(expr-with-v-and-acc)
base = Translate NEREUS (exp)
IN
iterate (collection, f, base)
END-LET
collection -> iterate (v: Element; acc: Type = exp |
expression-with-v-and-acc)
iterate (collection, f, base)
WHERE
OPERATIONS
f: Element x Type -> Type
base: -> Type
AXIOMS v: Element; acc: Type
f (v, acc)=TranslateNEREUS (expr-with-v-and-acc)
base = Translate NEREUS (exp)
END-WHERE
90
91
ASSOCIATES
<<Participates>>
END-CLASS
CLASS Meeting
IMPORTS String, Date, Boolean, Time
INHERITS Box_ Meeting [Box_Meeting: Meeting]
ASSOCIATES <<Participates>>
AXIOMS
END-CLASS
The following specifications of Person and Meeting result by flattening the classes Box_Person and
Box_Meeting respectively.
CLASS Person
IMPORTS Nat, String
EFFECTIVETYPES
Person
ATTRIBUTES
get_name: Person String
get_affiliation: Person String
get_address: Person String
OPERATIONS
createPerson: String x String x String Person
set_name: Person x String Person
set_affiliation: Person x String Person
set_address: Person x String Person
DEFERREDOPERATIONS
numMeeting: Person Nat
numConfirmedMeeting: Person Nat
AXIOMS cp: Person; t1, t2, t3, tp1, tp2, tp3: String
get_name (createPerson (t1, t2, t3)) = t1
get_affiliation (createPerson (t1, t2, t3)) = t2
get_address (createPerson (t1, t2, t3)) = t3
set_name (createPerson (t1, t2, t3), tp2) = createPerson (tp1, t2, t3)
set_affiliation (createPerson (t1, t2, t3), tp2) = createPerson (t1,
tp2, t3)
set_address (createPerson (t1, t2, t3), tp3) = createPerson (t1, t2, tp3)
END-CLASS
CLASS Meeting
IMPORTS String, Date, Boolean, Time
92
EFFECTIVETYPES Meeting
GENERATED-BY createMeeting
OPERATIONS
createMeeting: String x Date x Date x Boolean -> Meeting
title: Meeting -> String
start: Meeting -> Date
end: Meeting -> Date
isConfirmed: Meeting -> Boolean
set_title: Meeting x String -> Meeting
set_start: Meeting x Date -> Meeting
set_end: Meeting x Date -> Meeting
set_isConfirmed: Meeting x Boolean -> Boolean
AXIOMS s: String; d, d1: Date; b: Boolean;
title (createMeeting (s, d, d1, b)) = s
start (createMeeting (s, d, d1, b)) = d
end (createMeeting (s, d, d1, b)) = d1
isConfirmed (createMeeting (s, d, d1, b)) = b
...
END-CLASS
The association Participates can be built by instantiating the scheme ASSOCIATION_:
ASSOCIATION Participates
IS Bidirectional-Set [Person: Class1; Meeting: Class2; participants:
role1; meetings: role2; *: mult1; *: mult2; +: visibility1; +: visibility2]
END
The Association Participates refers to Bidirectional-Set, a scheme belonging to the reusable component Association:
RELATION SCHEME Bidirectional-Set
-- Bidirectional /* to */ as Set
IS-SUBTYPE-OF BinaryAssociation [Person: Class1; Meeting: Class2]
IMPORTS Set_Person: Set [Person], Set_Meeting: Set [Meeting]
GENERATED-BY create, addLink
name, frozen, changeable, addOnly, getRole1, getRole2,
getMult1,getMult2, getVisibility1, getVisibility2, isRelated, isEmpty, rightCardinality, leftCardinality
EFFECTIVEOPERATIONS create: Typename -> Participates
addLink:Participates (b) x Person (p) x Meeting (m)-> Participates
pre: not isRelated (a, p, m)
93
94
OCL
NEREUS
95
Boolean; Pa:Participates
title (create_Meeting (s, d, d1, b)) = s
start (create_Meeting (s, d, d1, b)) = d
end (create_Meeting (s, d, d1, b)) = d1
set-tittle (create_Meeting (s, d, d1, b), sp) = create_Meeting (sp,
d, d1, b)
set-start (create_Meeting (s, d, d1, b), dp) = create_Meeting (s,
dp, d1, b)
set-end (create_Meeting (s, d, d1, b), d1p) = create_Meeting (s, d,
d1p, b)
duration (m) = timeDifference (end (m), start (m))
isConfirmed (cancel (m)) = False
isConfirmed (m) = checkDate (m) and NumConfirmedParticipants (m) >= 2
--Rule 1
checkDate (m) = forAll (me) (collect (p) (getParticipants (Pa, m),
[getMeetings (Pa, p)]), [consistent (m, me]) --Rule 1
Consistent (m, m1)=
not (isConfirmed (m1)) or (end (m) < start (m1) or end (m1) < start
(m))
NumConfirmedParticipants (m) = size (getParticipants (Participates, m))
--Rules 1, 2, 3
END-CLASS
For example, the following OCL specification:
context Person:: numMeetingConfirmed (): Nat
post: result= self.meetings -> select (isConfirmed) -> size
is translated into:
AXIOMS p: Person;...
NumConfirmedMeeting (p) =
TranslateNereus (self.meetings -> select (isConfirmed) -> size)
TranslateNereus (self.meetings -> select (isConfirmed) -> size) =
Size (TranslateNEREUS (self.meetings-> select (isConfirmed))
numConfirmedMeetings (p) = size(select (m) (getMeetings (Pa, p),
[isConfirmed(m)])
Figure 4 summarizes the phases of the translation of P&M.
96
reFerenceS
Favre, L. (2005). Foundations for MDA-based Forward Engineering. Journal of Object Technology
(JOT), 4(1), 129-153). Retrieved on July 20, 2009 from www.jot.fm
Favre, L., Martinez, L., & Pereira, C. (2005). Forward Engineering of UML Static Models. In M.
Khosrow-Pour (Ed.), Encyclopedia of Information Science and Technology (pp. 1212-1217). Hershey,
PA: Idea Group Publishing.
Hussmann, H., Cerioli, M., Reggio, G., & Tort, F. (1999). Abstract Data Types and UML Models. Report
DISI-TR-99-15. University of Genova.
MOF. (2006). MOF: Meta Object facility (MOF ) 2.0. OMG Specification formal/2006-01-01. Retrieved on July 20, 2009 from www.omg.org/mof
Padawitz, P. (2000). Swinging UML: How to make class diagrams and state machines amenable to constraint solving and proving. In A. Evans & S. Kent (Eds.) (LNCS, pp. 265-277). Heidelberg: SpringerVerlag.
QVT. (2008). QVT: MOF 2.0 Query, View, Transformation. Formal/2008-04-03. Retrieved on July 20,
2009 from www.omg.org
UML. (2009a). Unified Modeling Language: Infrastructure. Version 2.2. OMG Specification formal/2009-02-04. Retrieved on July 20, 2009 from www.omg.org.
UML. (2009b). UML: Unified Modeling Language: Superstructure. Version 2.2. OMG Specification:
formal/2009-02-02. Retrieved on July 20, 2009 from www.omg.org
97
98
Chapter 6
intrOductiOn
In this chapter we examine the relation between NEREUS and formal specification using CASL (Common Algebraic Specification Language) as a common algebraic language (Bidoit & Mosses, 2004).
CASL is an expressive and simple language based on a critical selection of known constructs such
as subsorts, partial functions, first-order logic, and structured and architectural specifications. A basic
specification declares sorts, subsorts, operations and predicates, and gives axioms and constraints.
Specifications are structured by means of specification building operators for renaming, extension and
combining. Architectural specifications impose structure on implementations, whereas structured specifications only structure the text of specifications.
CASL allows loose, free and generated specifications. The models of a loose specification include
all those where the declared functions have the specified properties, without any restrictions on the set
of values corresponding to the various sorts. In models of a generated specification, in contrast, it is
required that all values can be expressed by terms formed from the specified constructors, i.e. unreachable values are prohibited. In models of free specifications, it is required that values of terms are distinct
except when their equality follows from the specified axioms: the possibility of unintended coincidence
between their axioms is prohibited.
DOI: 10.4018/978-1-61520-649-0.ch006
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
CASL is at the center of a family of specification languages. It has restrictions to various sublanguages, and extensions to higher-order, state-based, concurrent, and other languages. CASL is supported
by tools and facilitates interoperability of prototyping and verification tools.
Algebraic languages do not follow similar structuring mechanisms to UML or NEREUS. The graph
structure of a class diagram involves cycles such as those created by bidirectional associations. However,
the algebraic specifications are structured hierarchically and cyclic import structures between two specifications are avoided. In the following, we describe how to translate basic specification in NEREUS into
CASL, and then we analyze how to translate associations (Favre, 2009), (Favre, 2006) (Favre, 2005).
99
In NEREUS it is possible to specify three different levels of visibility for operations: public, protected
and private. In CASL, a private visibility requires to hide the operation by means of the operator Hide.
On the other hand, a protected operation in a class is included in all the subclasses of that class, and it
is hided by means of the operator Hide or the use of local definitions.
The IMPORTS paragraph declares imported specifications. In CASL, the specifications are declared
in the header specification after the keyword given, or, like unions of specifications. A generic specification definition SN with some parameters and some imports is expressed as follows:
spec SN [SP1] [SP2] [SPn]
given SP1, SP2,..., SPm= SP1 and SP and
then
SP
end
SN refers to the specification that has parameter specifications SP1, SP2,... SPn, (if any). Parameters
should be distinguished from references to fixed specifications that are not intended to be instantiated such
as SP1, SP2, .., SPm(if any). SP1, SP2, are references to import that can be instantiated. Unions
also allow us to express inheritance relations in CASL. The translation of the expression in NEREUS
CLASS A
INHERITS B,C
is translated into the following expression in CASL
spec A = B and C
end
References to generic specifications always instantiate the parameters. In NEREUS, the instantiation
of parameters [C: B] where C is a class already existing in the environment and B is a component of A
and C is a subclass of B, constructs an instance of A in which the component B is substituted by C. In
CASL, the intended fitting of the parameter symbols to the argument symbols may have to be specified
explicitly by means of a fit C|-> B.
NEREUS and CASL have the similar syntax for defining local functions. Then, this transformation
is reduced to a simple translation.
NEREUS distinguishes incomplete and complete specifications. In CASL, the incomplete specifications are translated to loose specifications and complete ones to free specifications. If the specification
has basic constructors, it will be translated into generated specifications. However, if it is incomplete it
will be translated into loose generated specifications. Both NEREUS and CASL allow loose extensions
of free specifications.
The classes that include higher order operations are translated inside parameterized first-order
specifications. The main difference between higher order specifications and parameterized ones is that,
in the first approach, several function-calls can be done with the same specification and parameterized
specifications require the construction of several instantiations. Next, we show the translation of the
Collection specification (see Class Collection in Chapter 4) to CASL. Take into account that there are
100
as much functions f1, f2, f3, and f4 as functions select, reject, forAll and exists. There are as much functions base and g as functions iterate too.
spec Operation [ sort X] =
Z1 and Z2 and ... Zr
thenpred
| 1 j m
f1j: X
| 1 j n
f2j: X
| 1 j k
f3j: X
| 1 j l
f4j: X
ops
basej: -> Zj | 1 j r
gj: Zj x X -> Zj | 1 j r
end
spec Collection [sort Elem]
given NAT= OPERATION [Elem]
thengenerated type
Collection::= create | add (Collection ; Elem)
pred
isEmpty: Collection
includes: Collection x Elem
includesAll: Collection x Collection
forAlli: Collection |1 i k
existsi: Collection |1 i l
iteratei: Collection Zj | 1 i r
ops
size: Collection Nat
selecti: Collection Collection |1i m
rejecti: Collection Collection |1i n
forall c, c1: Collection; e: Elem
isEmpty (create)
includes (add (c, e), e1) = if e = e1 then true else includes (c,
e1)
selecti (create) = create
selecti (add (c, e)) =
if f1i (e) then add (selecti (c), e) else selecti (c) |1i m
includesAll (c, add (c1, e)) = includes(c, e) and includesAll (c, c1)
rejecti (create) = create
rejecti (add (c, e))=
if not f2i (e) then add (rejecti (c), e) else rejecti (c) |1 i n
forAlli (add (c, e))= f3i (e) and for-alli (c) |1 i k
existsi (add (c, e))= f4i (e) or existsi (c) |1 i l
iteratej (create) = basej
101
tranSLating aSSOciatiOnS
NEREUS and UML follow similar structuring mechanisms of data abstraction and data encapsulation.
The algebraic languages do not follow these structuring mechanisms in an UML style. In UML an association can be viewed as a local part of an object. This interpretation can not be mapped to classical
algebraic specifications which do not admit cyclic import relations.
We propose an algebraic specification that considers associations belonging to the environment in
which an actual instance of the class is embedded. Let Assoc be a bi-directional association between two
classes called A and B, the following steps can be distinguished in the translation process:
Step1: Regroup the operations of classes A and B distinguishing operations local to A, local to B
and, local to A and B and Assoc.
Step 2: Construct the specifications A and B from A and B where A and B include local operations to A and B respectively.
Step 3: Construct specifications Collection[A] and Collection[B] by instantiating reusable
schemes.
Step 4: Construct a specification Assoc (with A and B) by instantiating reusable schemes in the
component Association
Step 5: Construct the specification AssocA+B by extending Assoc with A, B and the operations
local to A, B and Assoc.
Figure 1 shows the relations among the specifications built in the different steps and partially depicts
the structure of CASL specifications in the shaded text.
Table 1.
Local to
Operations/Attributes
PERSON
Name
MEETING
PERSON, MEETING,
PARTICIPATES
103
Step 4: Construct a specification Participates (with PERSON and MEETING) by instantiating reusable schemes in the component Association
spec PARTICIPATES = SET-PERSON and SET-MEETING and
BINARY-ASSOCIATION [PERSON] [MEETING]
with BinaryAssociation |-> Participates
pred
isRightLinked: Participates x Person
isLeftLinked: Participates x Meeting
isRelated: Participates x Person x Meeting
ops
addLink: Participates x Person x Meeting -> Participates
getParticipants: Participates x Meeting -> Set [Person]
getMeetings: Participates x Person -> Set [Meeting]
remove: Participates x Person x Meeting -> Participates
a: Participates; p, p1: Person; m, m1: Meeting
def addLink (a, p, m) not isRelated (a, p, m)
def getParticipants (a, m) isLeftLinked (a, m)
def getMeetings (a, m) isRightLinked (a, m)
def remove (a, p, m) isRelated (a, p, m)
endspec
104
Step 5: Construct the specification PERSON&MEETING by extending Participates and the operations local to PERSON, MEETING and PARTICIPATES.
spec PERSON&MEETING = PARTICIPATES
thenops
numMeeting: Participates x Person -> Nat
numConfirmedMeetings: Participates x Person -> Nat
isConfirmed: Participates x Meeting -> Boolean
numConfirmedParticipants: Participates x Meeting -(Nat
checkDate: Participates x Meeting -(Participates
select: Participates x Set [Meeting] -(Set [Meeting]
collect: Participates x Set [Person] -(Bag [Meeting]
pred
forall: Participates x Set [Meeting] x Meeting
(s: Set [Meeting]; m: Meeting; pa: Participates; p: Person; m: Meeting; sp: Set [Person];
bm: Bag [Meeting]
forall (pa, including (s, m), m1) = isConsistent (pa, m, m1) and
forall (pa, s, m1)
select (pa, create-Meeting) = create-Meeting
select (pa, including (s, m)) = including (select (pa, s), m) when
isConfirmed (pa, m)
else select (pa, s)
collect (pa, create-Person, s) = asBag (create-Person)
collect (pa, including (sp, p)) = asBag (including (collect (pa,
sp), p))
numMeeting (pa, p) = size (getMeetings (pa, p))
isConfirmed (pa, m) = checkDate (pa, m) and numConfirmedParticipants
(pa, m) ((2
numConfirmedMeetings (pa, p) = size (select (getMeetings (pa, p))
checkDate (pa, m) = forall (pa, collect (pa, getParticipants(pa, m),
m)
isConsistent (pa, m, m1) =
not (isConfirmed (pa, m1)) or (end (m) (start (m1) or end (m1)
(start (m))
numConfirmedParticipants (pa, m) = size (getParticipants (pa, m))
end
Figure 2 depicts the relations among the specifications built in the different steps.
105
reFerenceS
Bidoit, M., & Mosses, P. (2004). CASL User Manual- Introduction to Using the Common Algebraic
Specification Language (LNCS 2900). Heidelberg: Springer-Verlag.
Favre, L. (2005). Foundations for MDA-based Forward Engineering. Journal of Object Technology
(JOT), 4(1), 129-153). Retrieved on July 20, 2009 from www.jot.fm
Favre, L. (2006). A Rigorous Framework for Model Driven Development. In K. Siau (Ed.), Advanced
Topics in Database Research, Vol. 5 (pp. 1-27). Hershey, PA: Idea Group Publishing.
Favre, L. (2009) A Formal Foundation for Metamodeling (LNCS 5570, pp. 177-191). Heilderberg:
Springer-Verlag.
106
107
Chapter 7
intrOductiOn
This chapter discusses the main steps for transforming NEREUS constructions into object oriented
languages. As an example, we use the Eiffel language that allows integrating specifications with Eiffel
contracts (Meyer, 1992). Figure 1 shows the main steps.
The Eiffel code is constructed gradually. First, associations and operation signature are translated.
The transformation is supported by reusable components. From OCL and NEREUS specifications it is
possible to construct contracts on Eiffel and /or feature implementations by applying heuristics.
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
Figure 2 depicts a specific Association component including schemes for the Eiffel language. It describes taxonomy of associations classified according to kind, degree, navigability and multiplicity.
The first level describes a hierarchy of incomplete specifications of associations using NEREUS and
OCL. Every leaf in this level corresponds to sub-components at the second level.
A realization sub-component is a tree of algebraic specifications: the root is the most abstract definition and the internal nodes correspond to different realizations of the root. For example, for a binary,
108
bi-directional and many-to-many association, different realizations through hashing, sequences, or trees
could be associated. These subcomponents specify realizations starting from algebraic specifications
of Eiffel libraries (Meyer, 1994).
The implementation level associates each leaf of the realization level with different implementations
in Eiffel. Implementation sub-components express how to implement associations and aggregations.
For example, a bi-directional binary association with multiplicity one-to-one will be implemented as
an attribute in each associated class containing a reference to the related object. On the contrary, if the
association is many-to-many, the best approach is to implement the association as a different class in
which each instance represents one link and its attributes.
For every ASSOCIATES clause, a scheme in the implementation level of the association component will
be selected and instantiated. In these cases, the implementation level schemes suggest including reference
attributes in the classes or introducing an intermediate class or container. Notice that the transformation
of an association does not necessarily imply the existence of an associated class in the generated code
as an efficient implementation can suggest including reference attributes in the involved classes.
The following scheme may be used to implement bidirectional associations. It include two schemes
for classes Class1 and Class2
eiffel-Bidirectional-Set Scheme
classClass1
...
feature {NONE}
-- data members for association Association_Name
rol2: UnboundedCollectionbyReference [Class2];
mult_rol1: MULTIPLICITY;
-- operations for association Association_Name
get_mult_rol2: MULTIPLICITY isdo
Result:= mult_rol2end;
get_frozen_rol2: BOOLEAN isdo
Result:= result_frozen1end;
add_only_rol2: BOOLEAN isdo
Result:= result_add_only1end;
changeable_rol2: BOOLEAN isdo
Result:= result_changeable1end;
cardinality_rol2: INTEGER isdo
Result:= rol2.count
end;
set_ rol2 (d:UnboundedCollectionbyReference [Class2]) isrequire
get_mult_rol2.get_upper_bound >= d.count
dorol2:= d
end;
109
get_ rol2:
UnboundedCollectionbyReference[Class2] isdo
Result:= rol2end;
remove_rol2 (e: Class2) isrequire
is-related_rol2 (e) and not get_frozen_rol2 and not add-only_
rol2dorol2. prune (e)
end;
add_rol2 (e: Class2) isrequire is-related_rol2 (e) and not get_frozen_rol2 and cardinality_rol2get_mult_rol2.get_upper_bound
dorol2. put (e)
end;
add_rol2 (e:Class2) isrequire
is-related_rol2 (e) and
multiplicity_rol2get_mult_rol2.get_upper_bound and not get_frozen_
rol2
dorol2. put (e)
end;
is_related_rol2 (e: Class2): BOOLEAN isdo
Result:=rol2. has (e)
end;
invariant
mult_ rol2.get_lower_bound = LowerBound;
mult_ rol2.get_upper_bound = Upper Bound;
rol2.count >= LowerBound;
rol2.count <= Upper Boundend class Class1
-------------------------------------------------------------------classClass2
...
feature {NONE}
-- data members for association Association_Name
rol1: UnbondedCollectionby Reference [Class1];
mult_rol1: MULTIPLICITY;
-- operations for association Association_Name
...
add_rol1(e: Class1) isrequire
is-related_rol1 (e) and and not get_frozen_rol1 and multiplicity_
rol1get_mult_rol1.get_upper_bound
dorol1. put (e)
end;
110
Next, from the operation signatures, the interfaces for the features of the Eiffel class are generated.
The translation of each operation has a different treatment according to the type of feature to which it
makes reference (functions, procedures, variables, or constants). It should also be considered that of all
the domains of an operation, the first one that coincides with the sort of the specified class is the object
Current in Eiffel and it should be eliminated from the list of parameters of the resultant feature. Second
order functionalities of collections are translated respecting the syntax of the Eiffel schemes for Collection classes. As an example, we can generate code for the P&M Class Diagram described in Example
5-1 and translated into CASL in Example 6-1 by using the following textual substitution:
[Class1: Person; Class2: Meeting; rol1: participants; rol2: meetings; UnboundedCollectionbyReference: UnboundedSetbyReference; result_frozen1: false; result_add_only1: false,LowerBound1:2; UpperBound: *; ..]
Precondition: Expresses the requirements that the client must satisfy to call a routine.
Postcondition: Expresses the conditions that the routine guarantees on return.
Class invariant: Expresses the requirements that every object of the class must satisfy after its
creation.
111
The expression of the form old exp denotes the value that an attribute or expression exp had on
routine entry. Current refers to the target object itself and Result is the name of the returned object, if
there is any.
Let TranslateEiffel be a function that expresses the translation of a NEREUS term to Eiffel.
TranslateEiffel op(es,e2,e3,...) (where es, e2, e3 ... are well-formed non-ground terms and es is a
term of the sort of interest) can be given in the following inductive way:
TranslateEiffel op(es, e2, e3 ...) =
TranslateEiffel es.op (TranslateEiffele2, TranslateEiffel e3....)
Preconditions and axioms of a function written in NEREUS are used to generate preconditions and
postconditions for routines and invariants for Eiffel classes.
A NEREUS precondition, which is a well-formed term defined over functions and constants of the
global environment classes, is automatically translated to Eiffel precondition. Axioms are translated to
Eiffel post-conditions, invariants and implementations. We define two heuristics to obtain postconditions
and /or implementations in Eiffel:
reFerenceS
Meyer, B. (1992). Eiffel: The Language. Prentice Hall.
Meyer, B. (1994). Reusable Software: The Base object-oriented component libraries. Prentice Hall.
112
Table 1.
NEREUS
EIFFEL
class SET[G]
....
has (e: G):BOOLEAN
...
ensure
Result implies not empty
CLASS Meeting
...
Axioms p: Person
numMeetings (p)=
size(getParticipates (p))
class Meeting
...
numMeeting (p:PERSON)
do
Result:= meetings.size()
end
113
Section 3
Techniques Underlying
MDA-Based Reverse Engineering
115
Chapter 8
intrOductiOn
The success of MDA depends on the definition of model transformations and component libraries which
make a significant impact on tools that provide support for MDA. MDA is a young approach and several
technical issues are not adequately addressed. For instance, existing MDA-based CASE tools do not
provide adequate support to deal with component-based reuse (CASE, 2009). In light of this, we propose
a metamodeling technique to reach a high level of reusability and adaptability of components.
Reusability is the ability to use software elements for constructing many different applications. An
ideal software reusability tehnology should facilitate a consistent system implementation, starting from
the adaptation and integration of implementation pieces that exist in reusable components library.
Software reusability has two main purposes: to increase the reliability of software and to reduce the cost
of software development. Most current approaches to object oriented reusability are based on empirical methods. However the most effective forms of reuse are generally found at more abstract levels of
design (Krueger, 1992).
In MDA, software reusability is difficult because it requires taking many different requirements into
account, some of which are abstract and conceptual, while others, such as efficiency are concrete. A
good approach for MDA reusability must reconcile models at different abstraction levels.
In this chapter, we analyze how to define reusable components in a way that fits with MDA and
propose a megamodel for defining MDA components. Considering the relevant role that design patterns
take in software evolution we exemplify MDA components for them.
We propose a megamodel to define families of design pattern components by means of PIM-, PSMand ISM-metamodels and their interrelations. Instances of the megamodel are reusable components that
describe specific design patterns at different levels of abstraction (PIMs, PSMs and ISMs). They can be
DOI: 10.4018/978-1-61520-649-0.ch008
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
viewed as megacomponents that allow defining in a concise way as many components as different pattern solutions can appear. We analyze metamodel transformations of both PIMs into PSMs, and PSMs
into ISMs (Favre, & Martinez, 2006).
The traditional techniques for verification and validation are still essential to achieve software quality. We describe foundations for constructing formalizations of design pattern component. We define a
megamodel based on MOF-metamodels and metamodel-based model transformations and show how
to formalize them by using the metamodeling notation NEREUS. This notation, as we had said, can be
viewed as an intermediate notation open to many other formal languages (Favre, 2006) (Favre, 2005).
We illustrate our MDA-based approach by using the Observer design pattern.
Considering design patterns is a relevant technique in software development, in particular in forward
and reverse engineering processes we include some references to related work and remark the contribution of an MDA approach.
reLated WOrK
This section shows the evolution of design pattern techniques and remarks the advantages of an MDA
approach to define design pattern components.
In (Budinsky, Finni, Vlissides, & Yu, 1996) a tool to automatically generate code of design patterns
from a small amount of information given by the user is described. This approach has two widespread
problems. The user should understand what to cut and where to paste and both cannot be obvious.
Once the user has incorporated pattern code in his application, any change that implies to generate the
code again will force it to reinstate the pattern code in the application. The user cannot see changes in
the generated code through the tool.
Florijn, Meijers, and van Winsen, (1997) describe a tool prototype that supports design pattern during
the development or maintenance of object-oriented programs.
Albin-Amiot and Guhneuc (2001) describe how a metamodel can be used to obtain a representation
of design patterns and how this representation allows both automatic generation and detection of design
patterns. The contribution of this proposal is the definition of design patterns as entities of modeling
of first class. The main limitation of this approach concerns the integration of the generated code with
the user code.
Judson, Carver and France (2003) describe an approach to rigorous modeling of pattern-based transformations that involve specializations of the UML metamodel to characterize source and target models.
Kim, France, Ghosh, and Song (2003a) describe a metamodeling approach to specify design patterns using roles. They analyze the characteristics of object-based roles and generalize them. Based on
the generalized notion of a role, they define a new notion of a model role which is played by a model
element. The approach is intended to be easy to use and practical for the development of tools that incorporate patterns into UML models.
Kim, France, Ghosh, and Song (2003b) describe a metamodeling approach that uses a pattern specification language called Role-Based Modeling Language (RBML). A pattern specification defines a
family of UML models in terms of roles, where a role is associated with a UML metaclass as its base.
RBML uses visual notations based on the UML and textual constraints expressed in OCL to specify
patterns properties. The RBML allows specifying various perspectives of design patterns such as static
structure, interactions and state-based behavior.
116
France, Kim, Ghosh, and Song (2004) present a technique to specify pattern solutions expressed in
the UML. The specifications created by this technique are metamodels that characterize UML design
models of pattern solutions. The patterns specification consists of a Structural Pattern Specification (SPS)
that specifies the class diagram view of pattern solutions, and a set of Interaction Pattern Specification
(IPSs) that specifies interactions in pattern solutions. A UML model conforms to a pattern specification
if its class diagram conforms to the SPS and the interactions described by sequence diagrams conform
to the IPSs.
Component-based approaches have been proposed to reuse (DSouza & Wills, 1999) (Szyperski,
Gruntz, & Murer, 2002).
Bettin (2003) summarizes lessons from several projects related to component-based development
and MDA and examines the pragmatic use of todays MDA tools.
Meyer (2003) discusses the concept of Trusted Components, a reusable software element possessing specified and guaranteed property quality and examines a first framework for a Component Quality
Model. Arnout (2004) analyzes the popular Gammas design patterns (Gamma, Helm, Johnson and
Vlissides, 1995) to identify which ones can become reusable components in an Eiffel library.
In this chapter, we show how to integrate design patterns components with MDA-based processes.
The following advantages between our approach and some existing ones are worth mentioning. We define a megamodel to define families of reusable design pattern components. It refers to metamodel and
transformations organized in an architectural framework. A design pattern metamodel allows detecting
the presence of a pattern in a family of models. If there were no metamodels, a library of models specifying each one the ways in that the design pattern can appear should be necessary (this is expensive).
Also, it should be necessary to compare the model that is analyzed with the models of the library to see
if matching exists. On the other hand, the specification of the metamodels in the three levels allows us
to refine pattern model step-by-step in a MDA perspective.
117
describe families of refinements both between PIM- and PSM- metamodels and PSM- and ISM- metamodels respectively.
There are associations between metamodel and refinements so that each refinement links a source
metamodel and a target metamodel:
There is an association between the class PIM-Metamodel and the class Refinement PIM-PSM
specifying that each instance of PIM metamodel is connected with zero or more instances of the
Refinement PIM-PSM associated.
There is an association between the class PSM-Metamodel and the class Refinement PIM-PSM
specifying that each instance of PSM metamodel is connected with zero or more instances of the
Refinement PIM-PSM associated.
There is an association between the class PSM-Metamodel and the class Refinement PSM-ISM
specifying that each instance of PSM metamodel is connected with zero or more instances of the
Refinement PSM-ISM associated.
There is an association between the class ISM-Metamodel and the class Refinement PSM-ISM
specifying that each instance of PSM metamodel is connected with zero or more instances of the
Refinement PSM-ISM associated.
Figure 2 shows an instance of the megamodel that refers concrete instances of an Observer pattern
metamodel, refinements and, links between metamodels and refinements. Links connect an instance of a
refinement with an instance of a metamodel. The Observer pattern defines a one-to-many dependency
118
between objects so that when one object changes state, all its dependents are notified and updated automatically (Gamma et.al, 1995, pp. 293).
This instantiation can be viewed as a megacomponent defining a family of reusable components that
integrate instances of PIMs, PSMs and ISMs.
PIM Level: Metamodels describe design patterns in a way independent of platforms and specific
technologies.
PSM Level: Metamodels describe design patterns for specific platforms.
ISM Level: Metamodels describe design pattern in a specific programming language.
The definition of metamodels is based on popular catalogues: Gamma et al. (1995), Alpert, Brown
and Woolf (1998), Grand (1998), each one of them exemplifies design patterns by using C++, Smalltalk
y Java respectively.
Metamodels were specified taking into account:
Structure: Different representations of classes in the pattern, i.e. the different ways in which the
design pattern can appear at PIM level, where analyzed.
119
Participants: In view of each element that appears in the model must be specified in the respective metamodel, the classes and objects that participate in the pattern, their responsibilities and
interrelationships must be analyzed.
Collaborations: It was analyzed how participants collaborate to carry out their responsibilities
which revealed the operations that must be included in the pattern and therefore specified in the
metamodel.
Examples: Different applications and variants of patterns were exemplified in order that to check
metamodels.
120
Subject: It can contain any number of observers. It maintains a collection of observers and is
responsible for adding and removing observers of this collection (attach y detach). When state
changes (i.e. the values of some attributes change) the subject will notify observers of this situation (notify).
Observer: It can observe one or more subjects. It has the responsibility of updating itself when
receives a notification of change from the subject (update).
Collaborations
ConcreteSubject notifies its observers when there is a change that could make state of its observers inconsistent with its own.
After being informed of a change in the concrete subject, a ConcreteObserver object may query
the subject for information. ConcreteObserver uses this information to reconcile its state with that
of the subject.
Consequences
The Observer pattern allows us to vary subjects and observers independently. It is possible to reuse
subjects without reusing their observers, and vice versa. It lets us add observers without modifying the
subject or other observers.
Figure 3 shows the class diagram (a) and sequence diagram (b) that model the Observer pattern.
AbstractObserver: This metaclass specifies the characteristics of class Observer inside the
Observer pattern. It should have at least an operation with the characteristics of Update. Each instance of this metaclass can be an abstract class or an interface. If the instance is an abstract class,
a concrete observer inherits its behavior and, therefore there is an inheritance relation with the
concrete observer. If the instance is an interface, there is a realization relation with the concrete
observer.
ConcreteObserver: This metaclass specifies the characteristics of a concrete observer. It knows
the subject (or the subjects), then it is associated to ConcreteSubject through a unidirectional association navigable away from that end.
AbstractSubject: Each instance of this metaclass can be an abstract class or an interface and it has
at least three operations specified by Attach, Detach and Notify. If the instance of this metaclass is
121
an abstract class, all concrete subjects inherit its behavior therefore there is an inheritance relation
with the concrete subject. If the instance is an interface, there is a realization relation with the concrete subject. If the instance of AbstractSubject is an abstract class, it is associated to an instance
of AbstractObserver through a unidirectional association navigable away from that end.
ConcreteSubject: This metaclass specifies the characteristics of a concrete subject. It has at
least two operations specified by GetState and SetState and its internal state is specified by the
ObserverState metaclass.
The specialized UML metamodel of the Observer pattern is partially shown in Figures 4, 5, 6, and
7 (a,b,c,d). The shaded metaclasses correspond to metaclasses of the UML metamodel, whereas the
remaining corresponds to the specialization of the UML metamodel of the Observer pattern.
description of Metaclasses
Next, we describe the metaclasses of the metamodel at PIM level. For each one of them it is included
a brief description, generalizations, associations and restrictions in OCL and natural language. The
Observer pattern metamodel at PIM level specifies the structural and behavior views of this pattern in a
platform independent pattern model. It specifies the classes that participate, its operations and attributes
and the relation between classes.
122
123
124
AssocEndConcreteObserver
Description
It represents the association-end that links one association ObserverSubject, of which is a member, with
one ConcreteObserver.
Generalizations
Associations
participant: ConcreteObserver [1] It refers to the classifier that takes part in the association.
association: ObserverSubject [1] It refers to the association of which this association-end is member. It redefines Property::association
Constraints
[1] This association-end has a multiplicity n1..n2 (n1>= 0 and n2>=1) self.lower >= 0 and self.upper
>= 1
[2] It must be navigable self.isNavigable()
Additional Operations
[1] The observer operation isNavigable denotes if the association-end is navigable. isNavigable = not
self.class -> isEmpty ()
125
AssocEndObserver
Description
This property represents the association-end which connects an association SubjectObserver, of which
is member, with a class Observer.
Generalizations
Associations
participant: Observer [1] It denotes the classifier that participates in the association.
association: SubjectObserver [1] It denotes the association of which the association-end is member. It redefines Property::association.
Constraints
[1] This association-end has a multiplicity n1..n2 (n1>= 0 and n2>=1) self.lower >= 0 and self.upper
>= 1
[2] It must be navigable. self.isNavigable ()
AssocEndSubject
Description
This property represents the association-end which connects an association SubjectObserver, of which
is member, with a class Observer.
Generalizations
Associations
participant: Subject [1] It denotes the classifier that takes part in the association.
association: SubjectObserver [1] It denotes the association of which this association-end is member. It redefines Property::association.
Constraints
[1] This association-end has a multiplicity n1..n2 (n1 >= 0 and n2 >= 1) self.lower >= 0 and self.upper
>= 1
126
Attach
Description
It defines an operation that is declared by a Subject.
Generalizations
Associations
classSubject: ClassSubject [0..1] It denotes the class that declares this operation. It redefines
Operation::class.
interfaceSubject: InterfaceSubject [0..1] It denotes the interface that declares this operation. It
redefines Operation::interface.
Constraints
[1] This operation changes the state of the subject. not self.isQuery
[2] It has a nonempty set of parameters containing exactly one input parameter (direction=#in) whose
type is Observer. self.ownedParameter -> notEmpty () and self.ownedParameter -> select (param
| param.direction= #in and param.type = oclIsKindOf (Observer)) -> size() = 1
[3] Its visibility must be public self.visibility = #public
ClassObserver
Description
This metaclass specifies the features that a class taking the role of observer in the pattern must have.
Generalizations
Associations
update: Update [1..*] Every instance of the ClassObserver must have at least one operation that is
an instance of Update. It is a subset of Class::ownedOperation.
Constraints
No additional restrictions.
127
ClassSubject
Description
This metaclass specifies the features that a class taking the role of subject in the pattern must have.
Generalizations
Associations
attach: Attach [1..*] Every instance of ClassSubject has at least one operation that is an instance
of Attach. It is a subset of Class::ownedOperation.
detach: Detach [1..*] Every instance of ClassSubject has at least one operation that is instance of
Detach. It is a subset of Class::ownedOperation.
notify: Notify [1..*] Every instance of ClassSubject has at least one operation that is an instance
of Notify. It is a subset of Class::ownedOperation.
Constraints
No additional constraints.
ConcreteObserver
Description
This metaclass specifies the features that must be have a class taking the role of Concrete Observer in
the pattern.
Generalizations
Associations
Constraints
[1] Instances of concrete observers should not be abstract classes. not self.isAbstract
128
Associations
assocEndConcreteSubject: AssocEndConcreteSubject [1] It denotes the association-end of the association ObserverSubject in which this classifier participates.
generalizationSubject: GeneralizationSubject [0..1] It designs a generalization where
ConcreteSubject takes the role of child (specific). It is a subset of Classifier::generalizacin.
getState: GetState [1..*] Every instance of ConcreteSubject must have one or more operation instances of GetState operation. They can be own or inherited. It is a subset of NameSpace::member.
interfaceRealizationSubject: InterfaceRealization [0..1] It designs an interface realization where
ConcreteSubject takes the role of classifier implementing the contract (implementingClassifier).
It is a subset of BehavioredClassifier::InterfaceRealization.
setState: SetState [1..*] Every instance of ConcreteSubject must have one or more operation instances of SetState operation. They can be own or inherited. It is a subset of NameSpace::member.
state: Property [1..*] It specifies a non-empty set of all attributes of ConcreteSubject. They can be
own or inherited. It is a subset of NameSpace::member.
Constraints
[1] An instance of a concrete subject should not be an abstract class. not self.isAbstract
[2] If an instance of the concrete subject participates in an interface realization, then it must be a
BehavioredClassifier. self.interfaceRealizationSubject -> notEmpty () implies self.oclIsKindOf
(BehavioredClassifier)
[3] State is a set of properties that are attributes but not association-ends. self.state -> forAll (p |
p.association -> isEmpty())
Detach
Description
It defines an operation that is declared by a subject.
129
Generalizations
Associations
classSubject: ClassSubject [0..1] It designs the class that declares this operation. It redefines
Operation::class
interfaceSubject: InterfaceSubject [0..1] It denotes the interface that declares this operation. It
redefines Operation::interface.
Constraints
[1] This operation changes the state of the subject. not self.isQuery
[2] It has a nonempty set of parameters, one of them must be an input parameter of type Observer. self.
ownedParameter -> notEmpty () and self.ownedParameter -> select (param | param.direction =
#in and param.type = oclIsKindOf (Observer)) -> size() = 1
[3] Its visibility must be public. self.visibility = #public
GeneralizationObserver
Description
This metaclass specifies a generalization between an observer (ClassObserver) and a concrete observer
(ConcreteObserver) in the pattern.
Generalizations
Associations
classObserver: ClassObserver [1] It denotes the general element of this relation. It redefines
Generalization::general.
concreteObserver: ConcreteObserver [1] It denotes the specific element of this relation. It redefines Generalization::specific.
Constraints
No additional constraints.
GeneralizationSubject
Description
This metaclass specifies a generalization between a subject (ClassSubject) and a concrete subject (ConcreteSubject) in the model of the Observer pattern.
130
Generalizations
Associations
classSubject: ClassSubject [1] It denotes the general element of this relation. It redefines
Generalization::general.
concreteSubject: ConcreteSubject [1] It denotes the specific element of this relation. It redefines
Generalization::specific.
Constraints
No additional constraints.
GetState
Description
It defines an operation that is member of ConcreteSubject. It specifies a service that may be required
by another object.
Generalizations
Associations
No additional operations.
Constraints
[1] It is an observer operation. self.isQuery
[2] Due to it must return the subject state, the set of parameter is not empty and at least, one of them
must have a direction equal to out or return. self.ownedParameter -> notEmpty () and self.ownedParameter ->select (par |par.direction = #return or par.direction = #out) -> size () >= 1
[3] Its visibility must be public. self.visibility = #public
InterfaceObserver
Description
An interface InterfaceObserver specifies the features that must have an interface taking the role of Abstract Observer in the model of the Observer pattern.
Generalizations
131
Associations
update: Update [1..*] Every instance of InterfaceObserver must have at least one operation that is
an instance of Update. It is a subset of Interface::ownedOperation.
Constraints
No additional constraints.
InterfaceSubject
Description
This metaclass specifies the features that must have an interface taking the role of abstract subject in
the model of the Observer pattern.
Generalizations
Associations
attach: Attach [1..*] Every instance of InterfaceSubject must have at least one operation that is an
instance of Attach. It is subset of Interface::ownedOperation.
detach: Detach [1..*] Every instance of InterfaceSubject must have at least one operation that is
an instance of Detach. It is a subset of Interface::ownedOperation.
notify: Notify[1..*] Every instance of InterfaceSubject must have at least one operation that is an
instance of Notify. It is a subset of Interface::ownedOperation.
Constraints
No additional constraints.
InterfaceRealizationObserver
Description
This metaclass specifies an interface realization between an abstract observer (InterfaceObserver) and
a concrete observer (ConcreteObserver) in the model of the pattern Observer.
Generalizations
Associations
132
concreteObserver: ConcreteObserver [1] It designs the element that implements the contract in
this relation. It redefines InterfaceRealization::implementingClassifier.
interfaceObserver: InterfaceObserver [1] It designs the element that defines the contract in this
relation. It redefines InterfaceRealization::contract.
Constraints
No additional constraints.
InterfaceRealizationSubject
Description
This metaclass specifies an interface realization between an abstract subject (InterfaceSubject) and a
concrete subject (ConcreteSubject) in the model of the pattern Observer.
Generalizations
Associations
concreteSubject: ConcreteSubject [1] It designs the element that implements the contract in this
relation. It redefines InterfaceRealization::implementingClassifier.
interfaceSubject: InterfaceSubject [1] It designs the element that defines the contract in this relation. It redefines InterfaceRealization::contract.
Constraints
No additional constraints.
Notify
Description
It defines an operation that is declared by a subject.
Generalizations
Associations
classSubject: ClassSubject [0..1] It designs the class that declares this operation. It redefines
Operation::class.
interfaceSubject: InterfaceSubject [0..1] It designs the interface that declares this operation. It
redefines Operation::interface.
133
Constraints
[1] It is an operation that does not change the state of the subject. self.isQuery
[2] Its visibility must be public. self.visibility = #public
Observer
Description
An Observer is a specialized classifier that specifies the features of the classifier taking the role of observer in the model of the pattern Observer. It is an abstract metaclass.
Generalizations
Associations
Constraints
No additional constraints.
ObserverSubject
Description
This metaclass specifies a binary association between two instances of Observer y Subject respectively.
Generalizations
Associations
Constraints
[1] It has two association-end. self.memberEnd -> size () = 2
134
SetState
Description
It defines an operation of ConcreteSubject. It specifies a service that can be required from other object.
Generalizations
Associations
There are no additional associations.
Constraints
[1] It is a non-observer operation. not self.isQuery
[2] The set of parameters is not empty and at least, one of them must be an input parameter. self.
ownedParameter -> notEmpty () and self.ownedParameter -> select (param | param.direction =
#in) -> size() >= 1
[3] Its visibility must be public. self.visibility = #public
Subject
Description
This metaclass is a specialized classifier that specifies the features that must have the instance taking
the role of subject in the model of the Observer pattern. It is an abstract metaclass.
Generalizations
Associations
Constraints
No additional constraints.
SubjectObserver
Description
This metaclass specifies a binary association between two classifiers: Subject y Observer.
135
Generalizations
Associations
Constraints
[1] There are two association-end members. self.memberEnd -> size () = 2
Update
Description
It defines an operation that is declared by Observer specifing a service that may be required from other
object.
Generalizations
Associations
classObserver: ClassObserver [0..1] It denotes a class that is declared by this operation. It redefines Operation::ownedOperation.
interfaceObserver: InterfaceObserver [0..1] It denotes the interface that is declared by this operation. It redefines Operation::ownedOperation.
Constraints
[1] This operation does not change the state of the observer. self.isQuery
[2] Its visibility must be public. self.visibility = #public
136
137
are abstract classes in Eiffel, and therefore, the relationships between instances of Observer and EffectiveObserver, and between the instances of Subject and EffectiveSubject are generalizations.
The metamodel establishes that a subject is related with an observer through a binary association to
which is connected by two end-associations. In the same way, the effective observer is linked through
a binary association to the effective subject.
A subject has at least three routine instances of the Attach, Detach y Notify operations. An observer
has at least a routine of Update.
138
An effective subject must have a state determined by an attribute or a set of attributes, which will be
objects of observation and, at least operations that allow us to obtain and modify their values. Attributes
and routines can be own or inherited.
139
Otherwise, if the subject is an interface, it is linked to a concrete subject through a realization where the
concrete subject implements the contract that is defined by the abstract subject.
Similar relations are established for the observer and the concrete observer. A subject is related with
an observer through a binary association to which is connected by association-ends. In case the subject
is an interface, this association can not appear. The concrete subject and the concrete object are linked
in the same way through a binary association. A subject has at least three method instances of Attach,
Detach y Notify.
An observer has at least an instance of Update. A concrete subject must have a state composed by
one or more fields, observer object, and at least methods that allow get and modify their values. Both
fields and methods, can be own or inherited.
140
The main difference with the PSM metamodel is that at ISM level does not include association constructs and on the other hand, appear implementation constructs.
The metamodel establishes that a subject can be a class of a Java interface. If it is a class will includes
at least three method instances of Attach, Detach y Notify, and a reference to its observers through an
attribute which can be an instance of ObserverReference or an instance of SubjectObserverReference.
In the first case, the attribute refers to the collection of observers. In the second case refers to the intermediate class that maintains the relation between subjects and observers.
Figure 13. ISM Java Observer metamodel: Class diagram
141
A class taking the role of observer can be a class or an interface Java and will have at least a method
instance of Update.
The metaclass ConcreteSubject specifies a Java class which has a state composes by a field or a set
of fields (which in turn are observer objects) and, at least methods that allow obtain and modify their
values. Both fields and methods can be own or inherited.
If an instance of ConcreteSubject is heir of an instance of ClassSubject, then it will inherit a field that
is instance of ObserverReference or instance of SubjectObserverReference, and hence does not need to
declare any reference to their observers. On the contrary, if it implements an interface that is instance
of InterfaceSubject, must declare a field, instance of ObserverReference or SubjectObserverReference,
to maintain information on their observers.
ConcreteObserver specifies a Java class which can inherit of a class that is instance of ClassObserver
or can implement an interface instance of InterfaceObserver and can maintain a reference to the subject
that is observed through an attribute instance of SubjectReference.
142
SubjectObserverAssociation specifies the Java class that maintains the relation between a subject
and their observers. This class has an attribute instance of SubjectObserverMapping that stores the links
between the subject and its observers. It must have methods for adding and removing such links and
notify to observers of the changes in the subject.
143
We specify metamodel-based model transformations as OCL contracts that are described by means
of the notation described in Chapter 3 (see Figure 4). Below, we partially exemplify a transformation
Observer Pattern component from a PIM to an Eiffel-based PSM.
Transformation PIM-UML to PSM-EIFFEL {parameters
sourceModel: Observer-PIM-Metamodel:: Package
targetModel: Observer-PSM-EIFFEL-Metamodel:: Package
preconditions-- TRUE for the general casepostconditionspost:-sourceModel and targetModel have the same number of classifiers.
targetModel.ownedMember -> select (oclIsTypeOf (EiffelClass)) ->
size () =
sourceModel.ownedMember -> select (oclIsTypeOf (Class)) -> size () +
sourceModel.ownedMember-> select (oclIsTypeOf (Interface)) -> size
()
post:-- for each interface sourceInterface in sourceModel exists a
class targetClass-- in targetModel so that:
sourceModel.ownedMember -> select (oclIsTypeOf (Interface)) ->
forAll (sourceInterface |
targetModel.ownedMember -> select (oclIsTypeOf (EiffelClass)) ->
exists (targetClass |
-- targetClass matches sourceInterface.
targetClass.oclAsType (EiffelClass).classInterfaceMatch
(sourceInterface.oclAsType (Interface))))
post:-- For each class sourceClass in sourceModel exists a class
targetClass in targetModel-- so that:
144
145
matches sourceOperation,
aClass.ownedOperation -> select (op |
not op.ownedParameter -> exists (direction = #return)) -> forAll
(sourceOperation|
self.ownedRoutine -> exists (targetProcedure |
targetProcedure.oclIsTypeOf (Procedure) and
targetProcedure.rutineOperationMatch (sourceOperation))) and
-- for each operation sourceOperation of aClass that returns a
result, exists a function targetFunction in--self that matches
with the first,
aClass.ownedOperation -> select (op |
op.ownedParameter -> exists (direction = #return)) -> forAll (sourceOperation|
self.ownedRoutine -> exists (targetFunction |
targetFunction.oclIsTypeOf (Function) and
targetFunction.rutineOperationMatch (sourceOperation))) and
-- the number of attributes plus the number of association-ends of
self is equal to-- the number of properties of aClass,
self.associationEnd -> size () + self.attribute -> size () = aClass.
ownedAttribute -> size () and
-- for each property sourceEnd of aClass, which is an associationend, exists-- in self an association-end targetEnd that matches
sourceEnd and
aClass.ownedAttribute -> select (end | end.association -> size () =
1) ->
forAll (sourceEnd | self.associationEnd -> exists (targetEnd |
targetEnd.propertyMatch (sourceEnd))) and
-- for each property sourceAtt of aClass, which is an attribute,
exists in self an attribute-- targetAtt that matches sourceAtt.
aClass.ownedAttribute -> select (att | att.association -> size () =
0) ->
forAll (sourceAtt | self.attribute -> exists (targetAtt |
targetAtt.propertyMatch (sourceAtt)))
Observer-PSM-EIFFEL -Metamodel:: EiffelClass:: classInterfaceMatch
(anInterface: Observer-PIM-Metamodel::Interface): Boolean
classInterfaceMatch (anInterface) =
-- the class to which this operation is applied (self) matches the
interface-- anInterface if:-- they have the same name,
self.name = anInterface.name and
-- self is deferred,
self.isDeferred and
-- they have the same visibility,
146
147
149
respectively. The source metamodel describes a family of packages whose elements are only classes
and associations. The postconditions establish correspondences among classes, their superclasses, parameters, operations, and associations. The transformation specification guarantees, for instance, that
for each class sourceClass in the source exists a class targetClass in the target model, both of them with
the same name, the same parent classes and same child classes and so on.
We describe a transformation from a model of the pattern Observer at PIM level to a PSM in the
Eiffel platform. The definition uses PIM and PSM metamodels as source and target parameters.
Postconditions establish mappings between classes and interfaces in the source model and classes
in the target one. The different relationships between the source and the target model are commented
in the text of the transformation. .
CLASS ClassObserver
IS-SUBTYPE-OF Class, Observer
ASSOCIATES
<<ClassObserver-Update>>
GENERATED_BY create
TYPES ClassObserver
OPERATIONS
create: * ClassObserver
END-CLASS
CLASS ClassSubject
150
ASSOCIATES
<<AssocEndSubject-SubjectObserver>>
<<AssocEndObserver-SubjectObserver>>
GENERATED_BY create
TYPES
SubjectObserver
OPERATIONS
create: * SubjectObserver
AXIOMS a: SubjectObserver ; AP: Association-Property
Size (get_memberEnd (AP, a)) = 2
END-CLASS
END-PACKAGE
Formalizing refinements
Instances of refinement classes are translated into NEREUS specifications by instantiating reusable
schemes (see Figure 18).
Below, the specification of the refinement between a PIM-UML and a PSM-Eiffel is shown. The
function TranslateNEREUS (transformation.precondition) that appears in the transformation scheme as
a precondition of the operation addLink translates into NEREUS the OCL precondition. The function
TranslateNEREUS (transformation.postcondition) that appears in the axioms translates into NEREUS
axioms the OCL postconditions. An instantiation of the transformation scheme is the following:
[TransformationName:PIM-UML to PSM-EIFFEL;
sourceMetamodel: Observer-PIM -Metamodel;
Figure 18. A scheme for translating refinements: From UML/OCL to NEREUS
154
targetMetamodel: Observer-PSM-EIFFEL-Metamodel;
precondition: OCLexp1;
postcondition: OCLexp2 ]
CLASS PIM-UML_to_PSM-EIFFEL
GENERATED-BY addLink
EFFECTIVETYPES
PIM -UML_to_PSM-EIFFEL
OPERATIONS
addLink:
Observer-PIM-Metamodel x Observer-PSM-EIFFEL-Metamodel PIM-UML_to_
PSM-EIFFEL
get-source: PIM -UML_to_PSM-EIFFEL Observer-PIM-Metamodel
get-target: PIM -UML_to_PSM-EIFFEL Observer-PSM-EIFFEL-Metamodel
equal: PIM-UML_to_PSM-EIFFEL x PIM-UML_to_PSM-EIFFEL Boolean
-- local operations (private)
classClassMatch:
Observer-PSM-EIFFEL-Metamodel::EiffelClass x Observer-PIMMetamodel::Class Boolean
classInterfaceMatch: Observer-PSM-EIFFEL-Metamodel::EiffelClass x
Observer-PIM-Metamodel::Interface Boolean
AXIOMS
m1: Observer-PIM-Metamodel, m2: Observer-PSM-EIFFEL-Metamodel;
t1, t2: PIM-UML_to_PSM-EIFFEL; PP: Package-PackageableElement;
e: Observer-PSM-EIFFEL-Metamodel::EiffelClass; c: Observer-PIM
-Metamodel::Class;
get-source (addLink (m1, m2)) = m1
get-target (addLink (m1, m2)) = m2
equal (t1, t2) = IF get-source (t1) = get-source (t2) and get-target
(t1) = get-target (t2)
THEN true ELSE false
-- TranslateNEREUS (Transformation.postcondition)-- sourceModel and
targetModel have the equal number of classifiers.
size (select (elem) (get_ownedMember(PP,m2), [oclIsTypeOf (elem,
EiffelClass)])) =
size (select (elem) (get_ownedMember (PP, m1), [oclIsTypeOf (elem,
Class)])) +
size (select (elem) (get_ownedMember (PP, m1), [oclIsTypeOf (elem,
Interface)])) and
-- For each interface sourceInterface in sourceModel exists a
class targetClass-- in targetModel so that:
forAll (sourceInterface) (select (elem) (get_ownedMember (PP, m1),
[oclIsTypeOf (elem, Interface)]),
[exists (targetClass) (select (elem) (get_ownedMember (PP,m2),
155
END-CLASS
reFerenceS
Albin-Amiot, H., & Guhneuc, Y. (2008). Abstract Design Patterns: A Round-trip. CiteSearX. Retrieved
on July 20, 2009 from http://www.st.informatik.tu-darmstadt.de:8080/phdws/PHDOOS.pdf
Alpert, S., Brown, K., & Woolf, B. (1998). The design Patterns Smalltalk Companion. Reading: AddisonWesley.
Arnout, K. (2004). From Patterns to Components. Ph. D. Thesis, Swiss Institute of Technology (ETH
Zurich). Retrieved on July 20, 2009 from http://se.ethz.ch/people/arnout/patterns/
Bettin, J. (2003). Practicalities of Implementing Component-Based Development and Model-Driven
Architecture. In Proceedings of the Workshop Process Engineering for Object-Oriented and ComponentBased Development, OOSPLA 2003, USA. Retrieved on July 20 from www.open.org.au/Conferences/
oopsla2003/PE_Papers/Bettin.pdf
Bezivin, J., Jouault, F., & Valduriez, P. (2004). On the need for Megamodels. In J. Bettin, G. van Emde
Boas, A. Agrawal, M. Volter, & J. Bezivin (Eds.), Proceedings of Best Practices for Model-Driven Software Development (MDSD 2004). OOSPLA 2004 Workshop. Vancouver, Canada. Retrieved on July 20,
2009 from www.softmetaware.com/oospla2004.
Budinsky, F., Finni, M., Vlissides, J., & Yu, P. (1996). Automatic code generation from design patterns.
IBM Systems Journal, 35(2), 151171.
CASE. (2009). CASE Tools. Retrieved on July 20, 2009 from www.objectsbydesign.com/tools/umltools_byCompany.html
156
DSouza, D., & Cameron Wills, A. (1999). On Components, and Framework with UML. Reading:
Addison-Wesley.
Favre, L. (2005). Foundations for MDA-based Forward Engineering. Journal of Object Technology
(JOT), 4(1), 129-153). Retrieved on July 20, 2009 from www.jot.fm
Favre, L. (2006). A Rigorous Framework for Model Driven Development. In K. Siau (Ed.), Advanced
Topics in Database Research, Vol. 5 (pp. 1-27). Hershey, PA: Idea Group Publishing.
Favre, L., & Martinez, L. (2006). Formalizing MDA Components. In Proceedings of 9th International
Conference on Software Reuse (LNCS 4039, pp. 326-339). Heidelberg: Springer-Verlag.
Florijn, G., Meijers, M., & van Winsen, P. (1997) Tool support for object-oriented patterns. In Proceedings of ECOOP97 (European Conference on Object Oriented Programming), Jyvskyl, Finland (pp.
472-795).
France, R., Kim, D., Ghosh, S., & Song, E. (2004). A UML-Based Pattern Specification Technique. IEEE
Transactions on Software Engineering, 30(3), 193206. doi:10.1109/TSE.2004.1271174
Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1995). Design Patterns. Elements of Reusable
Object-Oriented Software. Reading: Addison-Wesley.
Grand, M. (1998). Patterns in Java. A Catalog of Reusable Design Patterns Illustrated with UML. Wiley
Computer Publishing.
Judson, S., Carver, D., & France, R. (2003). A metamodeling approach to model transformation. OOPSLA Companion, 2003, 326327.
Kim, D., France, R., Ghosh, S., & Song, E. (2003b). A Role-Based Metamodeling Approach to Specifying
Design Patterns. In Proceedings of the 27th Annual International Computer Software and Applications
Conference (COMPSAC03) (pp. 452-457). Los Alamitos: IEEE Computer Society.
Krueger, C. (1992). Software Reuse. ACM Computing Surveys, 24(2), 131183.
doi:10.1145/130844.130856
Meyer, B. (2003). The Grand Challenge of Trusted Components. In Proceedings of the 25th International
Conference on Software Engineering, Portland, Oregon (pp. 660-667).
Szyperski, C., Gruntz, D., & Murer, S. (2002). Component Software: Beyond Object-Oriented Programming (2nd ed.). Reading: Addison-Wesley.
UML. (2009a). Unified Modeling Language: Infrastructure. Version 2.2. OMG Specification formal/2009-02-04. Retrieved on July 20, 2009 from www.omg.org.
UML. (2009b). UML: Unified Modeling Language: Superstructure. Version 2.2. OMG Specification:
formal/2009-02-02. Retrieved on July 20, 2009 from www.omg.org
157
158
Chapter 9
intrOductiOn
In MDA is crucial to define, manage, and maintain traces and relationships between different models,
and automatically transform them and produce implementations.
Refactoring is a powerful technique when is repeatedly applied to a model to obtain another one with
the same behavior but enhancing some non functionality quality factor such as simplicity, flexibility,
understandability and performance (Fowler, 1999) (Mens, Van Eetvelde, Demeyer & Janssens, 2005).
Refactorings are horizontal transformations for supporting perfective model evolution.
In MDA, a crucial part of the evolution from abstract models to executable components or applications
(forward engineering) or, from code to abstract models (reverse engineering) is accomplished by means
of refactoring. Although the most effective forms of refactorings are at the design levels (for example,
PIMs or PSMs), MDA-based CASE tools provide limited facilities for refactoring only on source code
through an explicit selection made by the designer (CASE, 2009).
MDA-based refactorings can be specified in OCL as contracts between meta-patterns (MOF metamodel), consisting of pre- and post-conditions that hold for the model before/after refactoring. Besides,
we propose an alternative formalization based on the NEREUS language. We propose a uniform treatment of refactoring at platform independent, platform specific and implementation specific abstraction
levels.
DOI: 10.4018/978-1-61520-649-0.ch009
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
Refactoring is an important technique in MDA processes such as forward engineering and reverse
engineering. In this context, refactoring techniques should be raised to higher levels of abstraction in
order to achieve software evolution.
We propose an MDA framework for refactoring that is structured at three different levels of abstraction linked to models, metamodels and formal specification. The model level includes different kind of
models (PIM, PSM, ISM) related by refinement.
Considering there is a need for rigorous techniques that address refactoring in a more consistent and
precise way, we propose a rigorous approach to identify refactorings by formal specification matching.
In the following sections we describe an MDA-based refactoring approach. First, we describe some
related work.
reLated WOrK
This section shows the evolution of refactoring techniques and remarks the advantages of an MDA approach.
The first relevant publication on refactoring was carried out by Opdyke (1992), showing how functionalities and attributes can migrate among classes, how classes can be joined and separated using a class
diagram notation (subset of current UML). Roberts (1999) completed this work describing techniques
based on refactoring contracts. Fowler (1999) is the classical book on code refactoring. It informally
analyzes refactoring techniques on Java source code, explaining the structural changes through examples
with class diagrams.
Several approaches provide support to restructure UML models. In (Suny, Pollet, LeTraon, and
Jzquel, 2001) a set of refactorings is presented and how they may be designed to preserve the behavior of UML models is explained. Mens, Demeyer, DuBois, Stenten, and Van Gorp (2003) provide an
overview of existing research in the field of refactoring. Porres (2003) defines and implements model
refactorings as rule-based transformations. Van Gorp, Stenten, Mens, and Demeyer (2003) propose a set
of minimal extensions to UML metamodel, which allows reasoning about refactoring for all common
object-oriented languages.
There is a tendency to integrate refactoring tools into industrial software development environments.
For example, Together ControlCenter (CASE, 2009) applies code refactoring on user requirements. Mens,
Van Eetvelde, Demeyer, and Janssens (2005) explore the use of graph rewriting for specifying refactorings and prove that them preserve some properties. (France, Ghosh, Song, & Kim, 2003), (Laplante, &
Neill, 2005) and Kerievsky (2004) describe methods for pattern-directed refactorings.
Long, Jifeng, and Liu (2005) formalizes Fowlers refactorings (Fowler, 1999) as refinement laws in
a relational calculus.
Batory (2007) explores the underlying connections among program refactoring, program synthesis
and MDD from an architectural meta-programming perspective.
Folli and Mens (2008) analyze refactoring of UML models in the context of graph transformation
approach. They use a specific graph transformation tool, AGG, and provide suggestions of how AGG
may be improved to better support model refactoring.
(Demeyer, Ducasse, & Nierstrasz, 2002), (Mens, & Tourwe, 2004), (Thomas, 2005) and (France &
Rumpe, 2007) describe the state-of-the-art of refactoring.
159
Mda-BaSed reFactOring
We propose an MDA framework for refactoring that is structured at three different levels of abstraction
linked to models, metamodels and formal specification (Favre & Pereira, 2008) (Favre & Pereira, 2006).
The model level includes different kind of models (PIM, PSM, ISM) related by refinement. At this level
refactorings are based on a set of model refactoring rules. The metamodel level imposes relations between
a source metamodel and a target metamodel, both represented as MOF-metamodels. Every PIM, PSM
and ISM is an instance of a MOF-metamodel.
The level of formal specifications links MOF-metamodels and metamodel-based refactorings to
formal specifications. We propose to formalize MOF-metamodels and metamodel-based transformations by using the NEREUS language. NEREUS can be used as a common specification language and
is connected with different semiformal, formal and programming languages. Figure 1 depicts the levels
of the framework.
In summary, in the level of models, the refactoring of instances of PIMs, PSMs and ISMs is based
on classical pattern-directed refactoring techniques, MOF-metamodels control the consistency of
these transformations and, NEREUS facilitates the connection of the metamodels with different formal
languages. NEREUS can be used to reason and ensure consistency of refactoring and to take advantage
of all existing theoretical background on formal methods, using different tools such as theorem provers,
model checkers or rewrite engines.
160
161
a mechanism to convert the elements of a pattern that are instances of a particular meta-pattern, into
elements of another pattern.
Refactorings could be specified as contract imposing relations between a source metamodel and a
target metamodel both represented as MOF- metamodel. Figure 3 and Figure 4 show the source and
target metamodels for the Extract-Composite. The source metamodel defines the family of source models
to which refactorings can be applied and the target metamodel characterizes models that are generated.
The models to be transformed and the resulting models of the transformations will be instances of the
corresponding metamodel.
The source and target metamodels include metaclasses linked to the essential participants in the
patterns of Figure 2: Composite, Component and Leaf and, three relationships: Composite-ComponentAssoc, Component-Leaf-Generalization and Component-Composite-Generalization. The metamodel also
Figure 4. The Extract Composite Refactoring: Target metamodel
162
shows metaclasses linked to properties such as AssEndComposite and AssEndComponent and, shaded
metaclasses that correspond to the UML metamodel.
We can remark the following differences between the source and target metamodel. On the one hand,
in the source metamodel, an instance of Component has two or more instances of Component-CompositeGeneralization (compositeSpecialization) and two or more association-ends (associationEnd).
On the other hand, in the target metamodel, an instance of Component has exactly one instance of
Component-Composite-Generalization and one association-end.
Abstract Syntax
Figure 3 shows the metaclasses linked to the essential participants in the source metamodel to which
can be applied the refactoring Extract Composite:
Composite, Component and Leaf, refer to one class of the model with special features,
CompositeComponentAssoc, ComponentLeafGeneralization andComponentCompositeGeneralization, refer particular relationships between the classes Composite, Component and Leaf,
AssEndComposite and AssEndComponent, represent class properties,
The source metamodel specifies an instance of Component that has two or more instances of ComponentCompositeGeneralization (compositeSpecialization), i.e., two or more generalizations that have
a subclass that is an instance of Composite.
On the other hand, an instance of Component has two or more association-ends (associationEnd),
each of them is linked to an association whose type is CompositeComponentAssoc which in turn, has
another association-end whose participant is an instance of Composite. An instance of Component has
one or more instances of ComponentLeafGeneralization, i.e., one or more generalizations that has a
subclass that is an instance of Leaf.
163
Generalizations
Attributes
No additional attributes.
Associations
association: CompositeComponentAssoc [1] It denotes the association that links the classes
Component and Composite. It redefines Property::association.
participant: Component [1] It denotes the class that participates in the association in this
association-end.
Constraints
No additional constraints
AssEndComposite
Description
It denotes the link between the association CompositeComponentAssoc and the class Composite.
Generalizations
Attributes
No additional attributes.
Associations
association: CompositeComponentAssoc [1] It refers to the association that links the classes
Component and Composite. It redefines Property::association.
participant: Composite [1] It denotes the class that participates in the association in this associationend.
Constraints
[1] The association-end is an aggregation or a composition. self.aggregation = #shared or self.aggregation = #composite
164
Component
Description
It represents a class having the role of Component in an inheritance hierarchy.
Generalizations
Attributes
No additional attributes.
Associations
associationEnd: AssEndComponent [2..*] It denotes the set of association-ends, in which the class
Component participates. These association-ends belong to associations that connect with the class
Composite.
compositeSpecialization: ComponentCompositeGeneralization [2..*] It specifies the set of generalizations in which Component is the superclass and a class Composite is a subclass.
leafSpecialization: ComponentLeafGeneralization [1..*] It specifies the set of generalizations in
which Component is the superclass and a class Leaf is the subclass.
Constraints
[1] The associations between Composite and Component are equivalent.
AssEndComposite
Description
It denotes the connection between the association CompositeComponentAssoc and the class Composite.
Generalizations
Attributes
No additional attributes.
Associations
165
participant: Composite [1] It refers to the class that participates in the association of this associationend.
Constraints
[1] The association-end is aggregation or composition. self.aggregation = #shared or self.aggregation
= #composite
Component
Description
It represents a class having the role of Component in an inheritance hierarchy.
Generalizations
Attributes
No additional attributes.
Associations
associationEnd: AssEndComponent [2..*] It denotes the set of association-ends (in which the class
Component participates) belonging to associations that are linked to the class Composite.
compositeSpecialization: ComponentCompositeGeneralization [2..*] It specifies the set of generalizations in which Component is the superclasss and a class Composite is the subclass.
leafSpecialization: ComponentLeafGeneralization [1..*] It specifies the set of generalizations in
which Component is the superclass and a class Leaf is the subclass.
Constraints
[1] The associations between Composite and Component are equivalent. self.associationEnd collect
(assEnd | assEnd.association) forAll (a1, a2 | a1 = a2 or a1.isEquivalentTo (a2))
[2] In each class Composite, that is subclass of Component, exists operations that have functionality equivalents to operations of other classes Composite. The operation isEquivalentOperationTo() verifies whether the operation passed as parameter is equivalent to the operation to
which the operation is applied. This implies that they verify signature, plug-in and exact match.
The operation isEquivalentOperationTo() is specified as additional operation in the UML metamodel (Appendix A).
-- for all class Composite, subclass of Component self.compositeSpecialization.child forAll (class |
-- exists operations class.ownedOperation exists (op | self.compositeSpecialization.child
excluding (class) forAll (c | c.ownedOperation exists (o |
-- functionally equivalent to operations of another classes Composite op.isEquivalentOperationTo
(o)))))
166
Local Operations
CompositeComponentAssoc:
isEquivalentTo (a: CompositeComponentAssoc): Boolean;
-- It verifies whether or no the association passed as parameter is equivalent to the
-- association to which the operation is applied, i.e., they are equivalent, except
-- their names; the other features are preserved.
isEquivalentTo (a) = (self.name = a.name or self.name <> a.name) and
self.isDerived = a.isDerived and self.visibility = a.visibility and
self.memberEnd forAll (a1End | a.memberEnd exists (a2End |
(a1End.name = a2End.name or a1End.name <> a2End.name) and
a1End.visibility = a2End.visibility and a1End.isLeaf = a2End.isLeaf and
a1End.isStatic = a2End.isStatic and a1End.isDerived = a2End.isDerived and a1End.isReadOnly
= a2End.isReadOnly and a1End.isDerivedUnion = a2End.isDerivedUnion and a1End.aggregation = a2End.aggregation and a1End.upper = a2End.upper and a1End.lower = a2End.lower
and a1End.subsettedProperty = a2End.subsettedProperty and a1End.redefinedProperty = a2End.
redefinedProperty))
ComponentCompositeGeneralization
Description
It represents a generalization that exists between classes Component and Composite.
Generalizations
Generalization(from Kernel)
Attributes
No additional attributes
Associations
parent: Component [1] It refers to a class that takes the role of parent in the generalization. It redefines Generalization::general.
child: Composite [1] It refers to a class that takes the role of child in the generalization. It redefines Generalization::specific.
Constraints
No additional constraints.
Component LeafGeneralization
Description
It represents a generalization that exists between the classes Component and Leaf.
167
Generalizations
Attributes
No additional attributes
Associations
parent: Component [1] It refers to a class that takes the role of parent in the generalization. It redefines Generalization::general.
child: Leaf [1] It refers to a class that takes the role of child in the generalization. It redefines
Generalization::specific.
Constraints
No additional constraints.
Composite
Description
It represents a class having the role of Composite in an inheritance hierarchy.
Generalizations
Attributes
No additional attributes
Associations
associationEnd: AssEndComposite [1] It denotes the set of association-ends, in which the class
Composite participates, belonging to associations that are linked to the class Component.
componentGeneralization: ComponentCompositeGeneralization [1] It specifies the set of generalizations in which Composite is the subclass and a class Component is the superclass.
It is a subset of Classifier::generalization.
Constraints
No additional constraints.
CompositeComponentAssoc
Description
It describes a binary association that relates the metaclasses Composite and Component.
168
Generalizations
Attributes
No additional attributes
Associations
Constraints
[1] CompositeComponentAssoc is a binary association; the only association-ends are assEndComposite
and assEndComponent. self.memberEnd -> size () = 2
Leaf
Description
It represents a class that is a leaf in the inheritance hierarchy.
Generalizations
Attributes
No additional attributes
Associations
Constraints
No additional constraints.
169
Description of Metaclasses
AssEndComponent
It describes the connection of CompositeComponentAssoc with the class Component.
Generalizations
Attributes
No additional attributes.
Associations
association: CompositeComponentAssoc [1] It refers to the association that connects the classes
Component and Composite. It redefines Property::association.
participant: Component [1] It denotes the class that participates in the association in this
association-end.
Constraints
No additional Constraints.
AssEndComposite
It denotes the connection of the association CompositeComponentAssoc with the class Composite.
Generalizations
Attributes
There are no additional attributes.
170
Associations
Constraints
[1] The association-end is aggregation or composition. self.aggregation = #shared or self.aggregation
= #composite
Component
It represents a class having the role of Component in an inheritance hierarchy.
Generalizations
Attributes
No additional attributes.
Associations
Constraints
No additional restrictions.
ComponentCompositeGeneralization
It represents the generalization that exists between the classes Component and Composite.
Generalizations
Attributes
No additional attributes.
171
Associations
parent: Component [1] It refers to the class that takes the role of parent in the relation of generalization. It redefines Generalization::general.
child: Composite [1] It refers to the class that takes the role of child in the generalization. It redefines Generalization::specific.
Constraints
No additional constraints.
ComponentLeafGeneralization
It denotes the generalization that exists between the classes Component and Leaf.
Generalizations
Attributes
No additional attributes.
Associations
parent: Component [1] It refers to the class that takes the role of parent in the generalization. It
redefines Generalization::general.
child: Leaf [1] It refers to the class that takes the role of children in the generalization. It redefines
Generalization::specific.
Constraint
No additional constraints.
Composite
It denotes a class having the role of Composite in an inheritance hierarchy.
Generalizations
Attributes
No additional attributes.
Associations
172
associationEnd: AssEndComposite [1] It denotes the set of association-ends (in which the class
Composite participates), belonging to associations that connect them with the class Component.
componentGeneralization: ComponentCompositeGeneralization [1] It specifies the set of generalization in which Composite is the subclass and a class Component is the superclass.
It is a subset of Classifier::generalization.
Constraints
No additional constraints.
CompositeComponentAssoc
It denotes a binary association that relates the metaclasses Composite and Component.
Generalizations
Attributes
No additional attributes.
Associations
assEndComposite: AssEndComposite [1] It refers to the association-end linked to the Composite
of the association CompositeComponentAssoc. It is a subset of Association::memberEnd.
Constraints
[1] CompositeComponentAssoc is a binary association, i.e. the only association-ends that are members
of the association are assEndComposite and assEndComponent. self.memberEnd -> size () = 2
Leaf
It denotes a class having the role of Leaf in the inheritance hierarchy.
Generalizations
Attributes
No additional attributes.
Associations
173
Constraints
No additional constraints.
Refactorings are specified as OCL contracts that are written by using the notation described in Chapter 3. Following, the Extract-Composite rule specifies the above steps as a transformation rule in OCL.
Comments in the text explain the different OCL expressions.
Transformation Extract-Composite {parametersource: Source Metamodel
Extract Composite:: Package
target: Target Metamodel Extract Composite:: Package
local operationspostconditionspost
-- For each instance of class Component(SourceClass) in the source,
source.ownedMember -> select (oclIsTypeOf (Component)) -> forAll
174
(sourceClass |
-- there is an instance of Component(targetClass) in the target
so that, target.ownedMember -> select (oclIsTypeOf (Component)) ->
exists (targetClass |
-- targetClass has only a generalization
-- its type is ComponentCompositeGeneralization,
-- targetClass is the parent of a class whose type is
Composite, targetClass.oclAsType (Component).compositeSpecialization
-> size() =1 and
-- targetClass has an only association-end relating with a
class
-- whose type is Composite, targetClass.oclAsType (Component).associationEnd -> size () =1 and
-- the set of subclasses of targetClass whose type is Leaf,
is equal -- to the set of subclasses of sourceClass whose type is
Leaf
targetClass.oclAsType (Component).leafSpecialization.child =
sourceClass. oclAsType (Component).leafSpecialization.child and
-- inherited attributes of NamedElement targetClass.name =
sourceClass.name and targetClass.visibility = sourceClass.visibility
and
-- targetClass has the following values for:
-- inherited attribute of RedefinableElement targetClass.
oclAsType (Class).isLeaf = sourceClass.isLeaf and
-- inherited attribute of Classifier targetClass.oclAsType
(Class).isAbstract = sourceClass.isAbstract and
-- inherited associations of Class
-- targetClass has the same set of nested classifiers as
-- sourceClass
targetClass.oclAsType(Class).nestedClassifier = sourceClass.oclAsType(Class).nestedClassifier and
-- targetClass has the same subset of own operations as
-- sourceClass
targetClass.oclAsType(Class).ownedOperation = sourceClass.oclAsType(Class).ownedOperation and
-- the set of own attributes of targetClass is the resulting
set of
--excluding to the set of own attributes of sourceClass, the
-- attributes that are the association-end that relates
sourceClass
-- with the different classes whose type is Composite in the
source-- package.and including the association-end that links it
with the
-- only class Composite in the target package,
175
targetClass.oclAsType(Class).ownedAttribute =
sourceClass.oclAsType(Class).ownedAttribute ->
excluding (sourceClass.oclAsType (Component).
associationEnd.association.assEndComposite) ->
including (targetClass. oclAsType (Component).
associationEnd.association.assEndComposite) and
-- inherited associations of Classifier
-- both classes have the same set of generalizations targetClass.oclAsType (Class).generalization = sourceClass.oclAsType
(Class).generalization and
-- both classes belong to the same package targetClass.
oclAsType (Class).package = sourceClass.oclAsType (Class).package
and
-- both classes have the same set of redefined classifiers targetClass.oclAsType (Class).redefinedClassifier = sourceClass.
oclAsType (Class).redefinedClassifier and
-- inherited associations of Namespace
-- both classes have the same restrictions targetClass.
oclAsType (Class).ownedRule = sourceClass.oclAsType (Class).ownedRule and
-- both classes have the same set of imported elements targetClass.oclAsType (Class).elementImport = sourceClass.
oclAsType (Class).elementImport))
post
-- for each instance of Composite (sourceClass), in the source package, source.ownedMember -> select(oclIsTypeOf (Composite)) -> forAll
(sourceClass |
-- exists an instance of Class (targetClass) in the target package, so that target.ownedMember -> select(oclIsTypeOf(Class)) ->
exists (targetClass |
-- the class of the package target (targetClass) has as parent a
-- class whose type is Composite, targetClass.oclAsType (Class).
superClass.oclIsTypeOf (Composite)) and
-- targetClass has the following values for:
-- inherited attribute of RedefinableElement targetClass.
oclAsType(Class).isLeaf = sourceClass.oclAsType (Composite).isLeaf
and
-- inherited attributes of NamedElement targetClass.name =
sourceClass.name and targetClass.visibility = sourceClass.visibility
and
-- inherited attribute of Classifier targetClass.oclAsType
(Class).isAbstract = sourceClass.oclAsType (Composite).isAbstract
and
-- for each operation of sourceClass sourceClass.oclAsType
176
end).
-- for each own attribute of sourceClass, sourceClass.oclAsType (Class).ownedAttribute -> forAll (sAt /
-- exists in targetClass or in its descending an attribute
with the
-- following properties
targetClass.oclAsType (Class).allDescendant.ownedAttribute
-> exists (tAt /
-- if the attribute of sourceClass is of type Composite
(from the
-- source metamodel)
if (sAt.type.oclIsTypeOf (Composite))
then
-- the type of the attribute of targetClass is Composite (from
-- the target metamodel);
tAt.type.oclIsTypeOf (Composite) and
-- and the remaining properties of the attribute are
-- preserved
tAt.visibility = sAt.visibility and
tAt.isLeaf = sAt.isLeaf and
tAt.isStatic = sAt.isStatic and
tAt.isDerived = sAt.isDerived and
tAt.isReadOnly = sAt.isReadOnly and
tAt.isDerivedUnion = sAt.isDerivedUnion and
tAt.aggregation = sAt.aggregation and
tAt.upper = sAt.upper and
tAt.lower = sAt.lower and
tAt.association = sAt.association and
tAt.owningAssociation = sAt.owningAssociation and
tAt.redefinedProperty = sAt.redefinedProperty and
tAt.subsettedProperty = sAt.subsettedProperty
else
-- on the contrary, the attributes of targetClass are equal to
-- whose of sourceClass
tAt = sAt
endif)) and
-- inherited associations of Classifier
-- both classes have the same set of generalizations targetClass.
oclAsType (Class).generalization = sourceClass.oclAsType (Class).
generalization and
-- both classes belongs to the same package targetClass.oclAsType
(Class).package = sourceClass.oclAsType (Class).package and
-- both classes have the same set of classifiers targetClass.
oclAsType (Class).redefinedClassifier = sourceClass.oclAsType
181
(Class).redefinedClassifier and
-- both classes have the same set of imported elements targetClass.oclAsType (Class).elementImport = sourceClass.oclAsType
(Class).elementImport and
else
-- on the contrary, targetClass is equal to sourceClass.
targetClass = sourceClass
endif))
}
The link tag (<A HREF= .>) contains an image tag (<IMG SRC >) that the parser handles
as a child of HTMLLinkTag. When the parser detects that the link tag contains an image tag, constructs
an object HTMLImageTag as child of the object HTMLLinkTag. Another tag such as HTMLFormTag
and HTMLTitleTag are also child containers.
Figure 5 and Figure 6 show an instance of the Extract Composite pattern of Figure 2. Figure 5 shows
a simplified hierarchy of the HyperText Markup Language (HTML) tags, that is an instance of the source
metamodel of Figure 2. The HTML tags can be form, link and image tag. The form and link tags are child
containers; for example, a link tag can contain an image tag. HTML tags can be: form, link and image.
The form and link tags are containers of children, that is to say, a link tag can contain an image tag.
182
Figure 5 exemplifies the Extract Composite refactoring rule at the PIM level specified in OCL (Favre,
& Pereira, 2007). (Kerievsky, 2004, pp. 214) describes this rule at the ISM-JAVA level.
The source pattern in Figure 2 depicts subclasses in a hierarchy that implement the same composite.
The rule application extracts a superclass that implements the composite removing duplicate behavior.
The main steps in the proposed transformation are: create a composite; make each class that contains
duplicate behavior a subclass of the composite and identify methods that are purely duplicated or partially duplicated across the subclasses of a composite. A purely duplicated method can be moved with
all child containers to the composite. If the method is partially duplicated only the common behavior
across all subclasses can be moved.
The classes HTMLLinkTag and HTMLFormTag are instances of the metaclass Composite of the source
metamodel of the Extract Composite refactoring, HTMLTag is an instance of the metaclass Component
and HTMLImageTag is an instance of the metaclass Leaf.
In this example, the application of the Extract Composite refactoring includes the following steps:
183
To identify patterns we propose to adapt the ideas of specification matching described in (Zaremski
&Wing, 1997). The HTMLLinkTag and HTMLFormTag classes are instances of the Composite metaclass
of the Extract Composite Source Metamodel, HTMLTag is an instance of the Component metaclass and
HTMLImageTag is an instance of the Leaf metaclass (Figure 2).
The refactoring rule needs to identify duplicate operations of the HTMLFormTag and HTMLLinkTag
classes. Under signature matching, the addTag operation of HTMLLinkTag class is matched by both
addTag and removeTag operations of the HTMLFormTag class.
Let the following match be:
Exact Pre/Post Match: Two specifications, S and S, satisfy the exact pre/post match if their
preconditions are equivalent and their postconditions are equivalent: match E-pre/p ost (S, S) = (Spre
<=> Spre) and (Spost <=> Spost)
Plug-In Match: Under this match, S is matched by any specifications S whose precondition is
weaker (to allow at least all of the conditions that S allows) and whose postcondition is stronger
(to provide a guarantee at least as strong as S): match plug-in (S, S) = (Spre => Spre) and (Spost =>
Spost)
S is behaviorally equivalent to S, since we can replace S with S and have the same observable
behavior, but this is not a true equivalence because it is not symmetric.
Then, under Plug-In Match, addTag operation of HTMLLinkTag class is only matched by addTag
operation of HTMLFormTag class. Let S be the specification of the addTag operation of the HTMLLinkTag class and let S be the specification of the addTag operation of the HTMLFormTag class with allTag
renamed to tag. The precondition requirement (Spre => Spre) holds, since Spre = Spre = true, so showing
match plug-in (S, S) reduces to proving (Spost => Spost), in OCL:
184
Operation Specification S
Specification Matching
HTMLLinkTag::removeTag
HTMLFormTag::removeTag
HTMLLinkTag::getTag
HTMLFormTag::getTag
matchE-pre/post(S, S)
HTMLLinkTag::toPlainTextTag
HTMLFormTag::toPlainTextTag
matchE-pre/post(S, S)
185
CLASS AssEndComponent
IS-SUBTYPE-OF Property
ASSOCIATES
<< AssEndComponent-Component >>
<< AssEndComponent-CompositeComponentAssoc >>
TYPES
AssEndComposite
OPERATIONS
create: * AssEndComponent
END-CLASS
CLASS CompositeComponentAssoc
IS-SUBTYPE-OF Association
ASSOCIATES
<< AssEndComposite-CompositeComponentAssoc >>
<< AssEndComponent-CompositeComponentAssoc >>
TYPES
CompositeComponentAssoc
OPERATIONS
create: * CompositeComponentAssoc
isEquivalentTo: CompositeComponentAssoc x CompositeComponentAssoc
->boolean
AXIOMS c, cc: CompositeComponentAssoc; AP: Association-Property
size (get-memberEnd (AP, cc)) = 2
isEquivalentTo (c,cc) = (get-isDerived (c) = get-isDerived (cc) and
get-visibility (c) = get-visibility (cc) and
(get-name (c)=get-name (cc) or get-name (c) <> get-name (cc))and
forAll (end1) (get-memberEnd (AP, c), [exists (end2) (get-memberEnd
(AP, cc),
[(get-name (end1) = get-name (end2) or get-name (end1) <> get-name
(end2))and
get-visibility (end1) = get-visibility (end2) and get-isLeaf (end1)
= get-isLeaf (end2) and
get-isStatic (end1) = get-isStatic (end2) and
get-isDerived (end1) = get-isDerived (end2) and
get-isReadOnly (end1) = get-isReadOnly(end2) and
get-aggregationv(end1) = get-aggregation (end2) and
get-upper (end1) = get-upper(end2) and get-lower(end1) = getlower(end2) and
get-subsettedProperty (end1) = get-subsettedProperty (end2) and
get-redefinedProperty (end1) = get-redefinedProperty (end2) ] ]))
END-CLASS
186
CLASS Component
IS-SUBTYPE-OF M_Class
ASSOCIATES
<< Component-ComponentCompositeGeneralization >>
<< Component-ComponentLeafGeneralization >>
<< AssEndComponent-Component >>
TYPES
Component
OPERATIONS
create: * Component
AXIOMS c: Component; Ap: AssEndComponent-Component;
Aa: AssEndComponent-CompositeComponentAssoc;
Cp: Component-ComponentCompositeGeneralization;
Oc: Class-Operation; Cc: ComponentCompositeGeneralization-Composite
forAll (a1,a2) (collect (assEnd) (get_associationEnd (Ap, c),
[get_association (Aa, assEnd)]), [a1 = a2 or isEquivalentTo(a1, a2)
])
forAll (cl) (collect (child) (get_compositeSpecialization (Cp, c),
[get_child (Cc, child) ]),
[exists (op) (get_ownedOperation (Oc, cl),
[forAll (c) (excluding (collect (child) (get_compositeSpecialization
(Cp, c),
[get_child (Cc, child)]), cl),
[exists (o) (get_ownedOperation (Oc, c)),
[isEquivalentTo (op, o)] ]]
END-CLASS
CLASS ComponentCompositeGeneralization
IS-SUBTYPE-OF Generalization
ASSOCIATES
<< ComponentCompositeGeneralization-Composite >>
<< Component-ComponentCompositeGeneralization >>
TYPES
ComponentCompositeGeneralization
OPERATIONS
create: * ComponentCompositeGeneralization
END-CLASS
CLASS ComponentLeafGeneralization
IS-SUBTYPE-OF Generalization
ASSOCIATES
<< Component-ComponentLeafGeneralization >>
<< ComponentLeafGeneralization-Leaf >>
187
TYPES
ComponentLeafGeneralization
OPERATIONS
create: * ComponentLeafGeneralization
END-CLASS
CLASS Leaf
IS-SUBTYPE-OF M_Class
ASSOCIATES
<< ComponentLeafGeneralization-Leaf >>
TYPES Leaf
OPERATIONS
create: * Leaf
END-CLASS
CLASS Composite
IS-SUBTYPE-OF M_Class
ASSOCIATES
<< ComponentCompositeGeneralization-Composite >>
<< AssEndComposite-Composite >>
TYPESComposite
OPERATIONS
create: * Composite
END-CLASS
ASSOCIATION AssEndComposite-Composite
IS Bidirectional-1 [Composite: class1; AssEndComposite: class2; participant: role1; associationEnd: role2; 1: mult1; 1: mult2; +: visibility1; +: visibility2]
END
ASSOCIATION AssEndComponent-Component
IS Bidirectional-5 [AssEndComponent: class1; Component: class2; associationEnd: role1; participant: role2; 2..*: mult1; 1: mult2; +:
visibility1; +: visibility2]
END
ASSOCIATION AssEndComposite-CompositeComponentAssoc
IS Bidirectional-1 [AssEndComposite: class1; CompositeComponentAssoc: class2; assEndComposite: role1; association: role2; 1: mult1;
1: mult2; +: visibility1; +: visibility2]
188
END
ASSOCIATION AssEndComponent-CompositeComponentAssoc
IS Bidirectional-1 [AssEndComponent: class1; CompositeComponentAssoc: class2; assEndComponent: role1; association: role2; 1: mult1;
1: mult2; +: visibility1; +: visibility2]
END
ASSOCIATION Component-ComponentCompositeGeneralization
IS Bidirectional-5 [ComponentCompositeGeneralization: class1; Component: class2; compositeSpecialization: role1; parent: role2; 2..*:
mult1; 1: mult2; +: visibility1; +: visibility2]
CONSTRAINED-BY
parent: redefines general
END
ASSOCIATION Component-ComponentLeafGeneralization
IS Bidirectional-5 [ComponentLeafGeneralization: class1; Component:
class2; leafSpecialization: role1; parent: role2; 1..*: mult1; 1:
mult2; +: visibility1; +: visibility2]
CONSTRAINED-BY
parent: redefines general
END
ASSOCIATION ComponentCompositeGeneralization-Composite
IS Composition-1 [Composite: whole; ComponentCompositeGeneralization: part; child: role1; componentGeneralization: role2; 1: mult1;
1: mult2; +: visibility1; +: visibility2]
CONSTRAINED-BY
child: redefines specific
componentGeneralization: subsets generalization
END
ASSOCIATION ComponentLeafGeneralization-Leaf
IS Composition-1 [Leaf: whole; ComponentLeafGeneralization: part;
child: role1; componentGeneralization: role2; 1: mult1; 1: mult2; +:
visibility1; +: visibility2]
END
END-PACKAGE
Instances of refactorings are translated into NEREUS specifications by instantiating the reusable
schemes shown in Figure 6.
Following we shows the specification of the refactoring ExtractCompositeRefactoring. The function
TranslateNEREUS (transformation.precondition) that appears in the transformation scheme as a precondi-
189
tion of the operation create translates into NEREUS precondition the OCL precondition. The function,
TranslateNEREUS (transformation.postcondition), that appears in the axioms translates into NEREUS axioms
the OCL postconditions. An instantiation of the transformation scheme is the following:
[name: ExtractComposite;
sourceMetamodel: ExtractCompositeSourceMetamodel;
targetMetamodel: ExtractCompositeTargetMetamodel;
OCLexp1: precondition;
OCLexp2: postcondition ]
CLASS ExtractCompositeRefactoring
[source: ExtractCompositeSourceMetamodel;
target: ExtractCompositeTargetMetamodel]
GENERATED-BY addLink
EFFECTIVETYPE
ExtractCompositeRefactoring
OPERATIONS
addLink: source x target ExtractCompositeRefactoring
get_source: ExtractCompositeRefactoring source
get_target: ExtractCompositeRefactoring target
...
AXIOMS
r: ExtractCompositerefactoring;
m1: source;
m2: target;
PP: PackageableElement-Package
get_source (addLink (m1, m2)) = m1
get_target (addLink (m1, m2)) = m2
forAll (sourceClass) (select (sourceC) (get_ownedMember(PP, m1),
[oclIsTypeOf(sourceC, Component)],
[exists (targetClass)
(select (targetC) (get_ownedMember(PP, m2),
[oclIsTypeOf(targetC, Component)]),
name (targetClass) = name (sourceClass) and
visibility (targetClass) = visibility (sourceClass)
........
END-CLASS
190
As a result, the Ready state will become the default initial state of the ACTIVE region, a transition
whose target is the ACTIVE state will lead the state machine to the Ready state.
191
To specify this refactoring, source and target metamodels are specified as specialized UML metamodels. Figure 9 shows the UML simplified metamodel of state machines and Figure 10 metamodels
for the Introduce State Refactoring.
Source metamodel establishes that a source model has at least a composite state (instance of CompositeState), which contains one or more regions (instances of aRegion) without initial pseudostate.
These regions have an inner state (instance of InnerState), which is the target of transitions (instances
of IncomingTransition) that cross boundaries of its containing composite state (Figure 10a).
Target metamodel establishes that a target model has at least a composite state (instance of CompositeState), whose regions (instances of aRegion) contain an initial pseudostate (Figure 10b).
192
Model refactoring is specified relating each element of the source model to one or more elements
of the target model at metamodel level. Following we partially shows the specification of the Introduce
Initial Pseudostate refactoring as an OCL contract emphasizing the main changes in the diagrams. The
refactoring specification is explained by comments.
Transformation Introduce Initial Pseudostate {
parameter
source: Source_Metamodel::StateMachine
target: Target_Metamodel::StateMachine
postcondition
-- A CompositeState in source model matches a CompositeState in
target model
-- (allVertex is an additional operation of the StateMachine metaclass of the UML metamodel) source.allVertex -> select(oclIsTy
peOf(CompositeState)) -> forAll (sourceState | target.allVertex -> select(oclIsTypeOf(CompositeState)) -> exists (targetState | targetState.oclAsType(CompositeState).matches(sourceState.
oclAsType(CompositeState)))) and
-- A Pseudostate in source model matches a Pseudostate in target
model source.allVertex -> select(oclIsTypeOf(Pseudostate)) -> forAll
193
Figure 10. Introducing initial pseudostate refactoring: Source and target metamodels
(sourcePState | .
local operations
Target_Metamodel::CompositeState matches (aSourceState: Target_
Metamodel::CompositeState): Boolean
matches (aSourceState) =
-- aSourceState and targetState (self) have the same name self.
name = aSourceState.name
and
194
195
Transition)))
and ))
and }
This example was previously analyzed in the context of graph transformation. Next, we discuss
advantages of our approach regarding the use of graph transformation to specify model refactoring according to the results shown in (Mens, 2006) and (Folli and Mens, 2008). Graph transformation allows
representing complex transformations in a compact visual way using a tool, however current state-ofthe-art in graph transformation does not suffice to easily define model refactorings, so their expressive
power needs to be increased (Folli and Mens, 2008, p. 11). Some limitations are:
the type graph, which represent UML metamodel, does not allow representing concepts like
Aggregation and Composition, which are represented by a more generic concept of association;
the type graph cannot expresses all well-formedness constraints imposed on the UML metamodel.
This problem can be resolved by adding additional global graph constraints but Trying to formalize OCL constraints as graph constraints, however, is a far from trivial task. (Folli and Mens,
2008, pp. 11).
In our approach metamodeling-based refactorings are specified as OCL contracts between MOF
metamodels which are defined as specializations of the UML metamodel itself. Aggregations and compositions can be specified and OCL constraints are included.
Considering there is a need for rigorous techniques that address refactoring in consistent and precise
way, we propose, on the one hand, a rigorous approach to identify refactorings by specification matching, and on the other hand a formalization in the NEREUS language.
reFerenceS
Batory, D. (2007) Program Refactoring, Program Synthesis, and Model Driven Development (LNCS
4420, pp. 156-171) Heidelberg: Springer-Verlag.
CASE. (2009). CASE Tools. Retrieved on July 20, 2009 from www.objectsbydesign.com/tools/umltools_byCompany.html
Demeyer, S., Ducasse, S., & Nierstrasz, O. (2002). Object-Oriented Reengineering Patterns. Amsterdam:
Morgan Kaufmann.
Favre, L., & Pereira, C. (2007). Improving MDA-based Process Quality through Refactoring Patterns.
1st International Workshop on Software Patterns and Quality (SPAQu07) Nagoya, Japan, December 3,
2007- 14th Asia-Pacific Software Engineering Conference (APSEC07) Information Processing Society
of Japan (pp. 17-22)
Favre, L., & Pereira, C. (2008). Formalizing MDA-based Refactorings. 19th Australian Software Engineering Conference (ASWEC 2008) (pp. 377-386). Los Alamitos: IEEE Computer Society.
196
Folli, A., & Mens, T. (2008) Refactoring of UML models using AGG. Electronic Communications of
the EASST. Volume 8: ERCIM Symposium on Software Evolution 2007 (pp. 1-15).
Fowler, M. (1999). Refactoring: Improving the Design of Existing Programs. Reading: AddisonWesley.
France, R., Ghosh, S., Song, E., & Kim, D. (2003). A metamodeling approach to pattern-based model
refactoring. Software IEEE, 20(5), 5258. doi:10.1109/MS.2003.1231152
France, R., & Rumpe, B. (2007). Model-driven Development of Complex software: A Research Roadmap. In Proceedings of the Future of Software Engineering (FOSE 2007) (pp. 37-54). Los Alamitos:
IEEE Computer Society.
Kerievsky, J. (2004). Refactoring to Patterns. Reading: Addison-Wesley.
Laplante, P., & Neill, C. (2005). Antipatterns: Identification, Refactoring and Management. Auerbach
Publications.
Long, Q., Jifeng, H., & Liu, Z. (2005). Refactoring and Pattern-directed Refactoring: A Formal Perspective. Technical Report 318, UNU-IIST, P.O. Box 3058, Macau.
Mens, T., & Tourw, T. (2004). A Survey of Software Refactoring. IEEE Transactions on Software
Engineering, 30(2), 126139. doi:10.1109/TSE.2004.1265817
Mens, T., Van Eetvelde, N., Demeyer, S., & Janssens, D. (2005). Formalizing refactorings with graph
transformations. Journal of Software Maintenance, 17(4), 247276. doi:10.1002/smr.316
Mens, T., Van Gorp, P., Varr, D., & Karsai, G. (2006). Applying a Model Transformation Taxonomy to
Graph Transformation Technology. Electronic Notes in Theoretical Computer Science, 152, 143159.
doi:10.1016/j.entcs.2005.10.022
Mens, T., Demeyer, S., Du Bois, B., Stenten, H., &. Van Gorp, P. (2003). Refactoring: Current Research
and Future Trends. In Proceedings of Third Workshop on Language Descriptions, Tools and Applications (LDTA 2003) (pp. 120-130).
MOF. (2006). MOF: Meta Object facility (MOF ) 2.0. OMG Specification formal/2006-01-01. Retrieved on July 20, 2009 from www.omg.org/mof
Opdyke, W. (1992). Refactoring Object-Oriented Frameworks. PhD thesis, University of Illinois,
Urbana-Champaign.
Porres, I. (2003). Model Refactorings as Rule-Based Update Transformations (LNCS 2863, pp. 159-174.
Heidelberg: Springer-Verlag.
Roberts, D. (1999). Practical Analysis for Refactoring. PhD thesis, University of Illinois.
Suny, G., Pollet, D., LeTraon, D., & Jzquel, J. (2001). Refactoring UML Models (LNCS 2185, pp.
134-138). Heidelberg: Springer-Verlag.
Thomas, D. (2005). Refactoring as Meta Programming? Journal of Object Technology, 4(1), 7-11. Retrieved on July 20, 2009 from http://www.jot.fm/issues/issue_2005_01/column1
197
Zaremski, A., &. Wing, J. (1997). Specification Matching of Software Components. ACM Transactions
on Software Engineering and methodology. Vol. 6, 4 (pp. 333 - 369).
Van Gorp, P., Stenten, H., Mens, T., & Demeyer, S. (2003). Towards automating source-consistent UML
Refactorings (LNCS 2863, pp. 144-158). Heidelberg: Springer Verlag.
198
199
Chapter 10
MDA-Based Object-Oriented
Reverse Engineering
intrOductiOn
Reverse engineering is the process of analyzing software systems to extract software artifacts at a higher
level of abstraction so that it is easier to understand them, e.g., for reengineering, modernizing, reuse,
migration or documenting purposes.
This chapter describes an approach to reverse engineering object oriented code. A central idea in
reverse engineering is exploiting the source code as the most reliable description both of the system
behavior and of the organization and its business rules.
We propose an approach for MDA-based object oriented reverse engineering that integrates classical compiler techniques, metamodeling techniques and formal specification for recovering designs and
architectures.
We analyze reverse engineering of PSMs and PIMs from object-oriented code. Models are expressed
using UML and OCL. On the one hand, the subset of UML diagrams, that are useful for platform-dependent models, includes class diagram, object diagram, state diagram, interaction diagram (collaboration
diagram and sequence diagram) and package diagram. On the other hand, a PIM can be expressed by
means of use case diagrams, activity diagrams, interaction diagrams to model system processes and state
diagrams to model lifecycle of the system entities.
DOI: 10.4018/978-1-61520-649-0.ch010
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
Reverse engineering involves processes with different degrees of automation, which can go from
totally automatic static analysis to human intervention requiring processes to dynamically analyze the
resultant models. Then, we analyze static and dynamic analysis techniques for recovering models at
different abstraction levels.
We show how MOF-based metamodels can be used to drive model recovery processes. Besides, considering that validation, verification and consistency analysis are crucial activities in the modernization of
systems, we propose an algebraic formalization of these MOF-defined reverse engineering processes.
Next, we describe related work and the features of existing reverse engineering tools.
reLated WOrK
Many works had contributed to reverse engineering object oriented code. (Muller, Jahnke, Smith, Storey,
Tilley, & Wong, 2000) presents a roadmap for reverse engineering research for the first decade of the
2000s. (Angyal, Lengyel, & Charaf, 2006) is an overview of the state-of-the-art of reverse engineering
techniques. A more recent survey of existing work in the area of reverse engineering is (Canfora & Di
Penta, 2007). This article compares existing work, discusses success and provides a road map for possible future developments in the area.
Fanta and Rajlich (1998) describe the reengineering of a deteriorated object-oriented industrial program
written in C++. In order to deal with this problem, they designed and implemented several restructuring
tools and used them in specific reengineering scenarios.
Systa (2000) describes an experimental environment to reverse engineer JAVA software that integrates
dynamic and static information.
Demeyer, Ducasse, & Nierstrasz (2002) distinguish a variety of techniques for object-oriented reengineering based on patterns.
Qiao, Yang, Chu and Xu (2003) present an approach to bridging legacy systems to MDA that includes
an architecture description language and a reverse engineering process.
Koehler, Hauser, Kapoor, Wu, and Kumaran (2003) describe a method that implements model
driven transformations between particular platform-independent (business views) and platform-specific
(IT architectural) models. On the PIM level, they use business process models and on the PSM level,
the IT architectural models are service-oriented and focus on specific platform using Web service and
workflows.
Gueheneuc (2004) proposes a study of class diagram constituents with respect to their recovery from
object oriented code.
Boronat, Carsi and Ramos (2005) describe MOMENT, a rigorous framework for automatic legacy
system migration in MDA.
MacDonald, Russell, and Atchison (2005) report on a project that assessed the feasibility of applying
MDD to the evolution of a legacy system.
Deissenboeck and Ratiu (2006) show the first steps towards the definition of a metamodel that unifies
a conceptual view on programs with the classical structure-based reverse engineering metamodels.
Tonella and Potrich (2005) provide a relevant overview of techniques that have been recently investigated and applied in the field of reverse engineering of object oriented code. They describe the
algorithms involved in the recovery of UML diagrams from code and some of the techniques that can
be adopted for their visualization. The algorithms deal with the reverse engineering of the following
200
diagrams: class diagram, object and interaction diagram, state diagram and package diagram. The underling principle in this approach is that information is derived statically by performing propagation of
proper data in a data flow graph.
(Greevy, Ducasse & Girba, 2005) describes a novel approach to analyze the evolution of a system
in terms of features reflecting how the functional roles of software artifacts change. They introduce
visualizations to support reasoning about the evolution of a system from a feature perspective.
Reus, Geers and van Deursen (2006) describe a feasibility study in reengineering legacy systems
based on grammars and metamodels.
The increased use of data warehouse and data mining techniques had motivated an interest in data
reverse technologies. In general, reverse engineering of persistent data structure of software systems is
more specifically referred to as database reverse engineering. Kagdi, Collard and Maletic (2007) provide a
survey and taxonomy of approaches for mining software repositories in the context of software evolution.
The term mining software repositories (MSR) describes a broad kind of research into the examination
of software repositories including artifacts that are produced and stored during software evolution. The
main contribution of this article is to present a layered taxonomy identifying four dimensions in order
to objectively describe and compare the different existing approaches.
Novel approaches analyze the evolution of a system in terms of features. A feature in a program
represents some functionality that is accessible by and visible to the developers, and usually captured by
explicit requirements. The process of identifying the parts of code that correspond to specific functionality is called feature (or concept) location and it is part of the incremental change process. (Pohyvanyk,
Gueheneuc, Marcus, Antoniol, & Rajlich, 2007) analyzes feature location using probabilistic ranking
of methods based on execution scenarios and information retrieval and, proposes a new technique for
feature location which combines an information retrieval technique with dynamic analysis.
Nowadays, software industry evolves to manage new platform technologies, design techniques and
processes and there is a need for information integration and tool interoperation based on Model Driven
Development (MDD). There is an increased demand of modernization systems that are still businesscritical in order to extend their useful lifetime. The success of system modernization depends on the
existence of technical frameworks for information integration and tool interoperation like the Model
Driven Architecture (MDA). Reverse engineering techniques play a crucial role in modernizing systems
in a way that fits with the Model Driven Architecture (MDA).
OMG is involved in the definition of standards to successfully modernize existing information systems.
The OMG Architecture-Driven Modernization (ADM) Task Force is developing a set of modernization standards with the purpose of software improvement, modifications, interoperability, refactoring,
restructuring, reuse, porting, migration and MDA migration.
In the following section we analyze different tools linked to reverse engineering.
caSe tOOLS
Twenty years ago, reverse engineering was focused mainly on recovering high-level architecture or
diagrams from procedural code to face up to problems such as comprehending data structures or databases, or the Y2K problem. At that time, many different tools for extracting intermediate representations from the source code and storing it into databases were built. Many reverse engineering tools have
been implemented to reverse engineering code written in procedural programming languages such as C
201
Visio
MDA-based tools
and Cobol (Antoniol, Fiutem, Lutteri, Tonella & Zanfei, 1997). Examples of tools include CIA (Chen,
Nishimoto, & Ramamoorthy, 1990) and the Software Refinery that used an object database, called Refine, to store artifacts in the form of an attribute Abstract Syntax Tree (Markosian, Newcomb, Brand,
Burson, & Kitzmiller, 1994).
A growing demand of reverse engineering systems appeared on the stage when object oriented languages emerged. The compiler techniques were adapted to perform a propagation of proper data in an
essentially dynamic context. During this time, the focus of software analysis moved from static analysis
to dynamic one. Many works has been aimed at identifying abstract data types in procedural code. This
process cannot be fully automated and the output of reverse engineering was only the starting point for
highly human-interaction reengineering.
Bellay and Gall (1998) evaluate the capabilities of reverse engineering tools by applying them to a
real-world embedded software system which implements part of a train control system. The selected
tools were Refine/C (Markosian, Newcomb, Brand, Burson, & Kitzmiller, 1994), Imagix4D (Imagix4D,
2000), SNiFF+ (SNiFF+, 1996) and Rigi (Muller & Klashinsky, 1988).
Amstrong and Trudeau (1998) examined tools focusing on the abstraction and visualization of system
components and interactions. The five tools they examine were: Rigi (Muller & Klashinsky, 1988), the
Dali workbench (Kazman, & Carriere, 1999), the Software Bookshelf (Finnigan, Holt, Kalas, Kerr, Kontogiannis et al, 1997), CIA (Chen, Nishimoto, & Ramamoorthy, 1990) and SNiFF+(SNiFF+, 1996).
When the Unified Modeling Language (UML) emerged, a new problem was how to extract higher
level views of the system expressed by different kind of diagrams. (Dwyer, Hatcliff, Joehanes, Laubach,
Pasareanu, Robby, Zheng, & Visser, 2001) describes an integrated collection of program analysis and
transformation components, called Bandera, that enables the automatic extraction of safe, compact
finite-state models from program source code.
The reverse engineering tool RevEng extracts UML diagrams from C++ code. Among the diagrams
that RevEng extracts are class diagram, object diagram, state diagram, sequence and collaboration diagrams and package diagram (Potrich & Tonella, 2000).
To date, there are about 150 UML CASE tools that vary widely in functionality, usability, performance and platforms (CASE, 2009). Some of them can only help with the mechanics of drawing and
exporting UML diagrams. The main stream object-oriented CASE tools support forward engineering
and reverse engineering processes and can help with the analysis of consistency between diagrams.
Only a few UML tools include extension for real time modeling. Table 1 exemplifies taxonomy of the
UML CASE tools (CASE, 2009).
The current techniques available in the commercial tools do not allow generating complete and executable code and after generation, the code needs additions. A source of problems in the code generation
202
processes is that, on the one hand, the UML models contain information that cannot be expressed in
object- oriented languages while, on the other hand, the object-oriented languages express implementation characteristics that have no counterpart in the UML models.
Moreover, the existing CASE tools do not exploit all the information contained in the UML models.
For instance, cardinality and constraints of associations and preconditions, postconditions, and class
invariants in OCL are only translated as annotations. It is the designers responsibility to make good use
of this information either selecting an appropriate implementation from a limited repertoire or implementing the association by himself.
On the other hand, many CASE tools support reverse engineering, however, they only use more
basic notational features with a direct code representation and produce very large diagrams. Reverse
engineering processes are facilitated by inserting annotations in the generated code. These annotations
are the link between the model elements and the language. As such, they should be kept intact and not
be changed. It is the programmers responsibility to know what he or she can modify and what he or
she cannot modify.
UML CASE tools provide limited facilities for refactoring on source code through an explicit selection made for the designer. However it will be worth thinking about refactoring at the design level. The
advantage of refactoring at UML level is that the transformations do not have to be tied to the syntax of
a programming language. This is relevant since UML is designed to serve as a basis for code generation
with the MDA paradigm (Sunye, Pollet, LeTraon, & Jezequel, 2001).
Techniques that currently exist in UML CASE tools provide little support for validating models in
the design stages. Reasoning about models of systems is well supported by automated theorem provers
and model checkers, however these tools are not integrated into CASE tools environments. Another
problem is that as soon as the requirements specifications are handed down, the system architecture
begins to deviate from specifications. Only research tools provide support for formal specification and
deductive verification.
Nowadays, software and system engineering industry evolves to manage new platform technologies,
design techniques and processes. A new architectural framework for information integration and tool
interoperation such as MDD had created the need to develop new analysis tools and specific techniques.
MDD refers to a range of development approaches that are based on the use of software models as first
class entities, one of them is MDA.
The success of MDA depends on the existence of CASE tools that make a significant impact on
software processes such as forward engineering and reverse engineering processes (CASE, 2009).
The tool market around MDA tools is still in flux and, only about 10% of UML Case tools provide
some support for MDA (CASE, 2009). All of the MDA tools are partially compliant to MDA features.
They provide good support for modeling and limited support for automated transformation. In general,
they support MDD from the PIM level and use UML class diagrams for designing PIMs. Some of them
provide only one level of transformation from PIM to code (Codagen, Ameos, Arcstyler) and, in general,
there is no relation between QVT and the current existing MDA tools. As an example, OptimalJ from
Compuware supports MDD from PIM level. It allows generating PSMs from a PIM and a partial code
generation. It distinguishes three kinds of models: a domain model that correspond to a PIM model, an
application model that includes PSMs linked to different platforms (Relational-PSM, EJB-PSM and
web-PSM) and an implementation model. The transformation process is supported by transformation
and functional patterns.
203
(Mansurov, & Campara, 2005) describes a tool-assisted way of introducing models in the migration
towards MDA. They propose to automatically extract architecturally significant models (called Container
models) and then refactoring them to achieve models in higher-level of abstraction.
Eclipse is an open source framework that can be extended by external plug-in and several transformation tools are implemented as Eclipse plug-in. Eclipse generative Modeling Tools (EclipseGMT) is
a collection of tools for model driven development (Eclipse, 2009). Atlas Transformation Language
(ATL) implements the MOF-metamodel Query, View, Transformation (QVT).
MetaEdit+ is an integrated environment for building and using solutions in a language that uses
concepts and rules from the problem domain, a Domain-Specific Language (DSL). High-level models
are expressed in a DSL and code can then be automatically generated from them using customized code
generators (MetaEdit, 2009).
The Fujaba Tool Suite project is suited to provide an easy to extend UML, Story Driven Modeling and
Graph Transformation platform with the ability to add plug-ins (FUJUBA, 2009). It combines UML static
diagrams and UML behavior diagrams (Story Diagrams). Furthermore, it supports the generation of Java
code. Fujaba is configured with plug-ins for Reverse Engineering and Design Pattern recognition.
The MDA-based tools use MOF to support OMG standards such as UML and XMI (XML Metadata
Interchange). MOF has a central role in MDA as a common standard to integrate all different kinds of
models and metadata and to exchange these models among tools; however, MOF does not allow capturing
semantic properties in a platform independent way and there is no rigorous foundations for specifying
transformations among different kinds of models.
204
in this context object-data flow. This static analysis is complemented with dynamic analysis supported
by tracer tools.
The metamodel level includes MOF metamodels that describe the transformations at model level
(MOF, 2006). A metamodel is an explicit model of the constructs and rules needed to construct specific
models. MOF metamodels use an object modeling framework that is essentially a subset of UML 2.2
core (UML, 2009a). The modeling concepts are classes which model MOF metaobjects, associations,
which model binary relations between metaobjects, data types which model other data, and packages
which modularize the models. At this level MOF metamodels describe families of ISMs, PSMs and PIMs.
Every ISM, PSM and PIM conforms to a MOF metamodel. Metamodel transformations are specified as
OCL contracts between a source metamodel and a target metamodel. MOF metamodels control the
consistency of these transformations.
The level of formal specification includes specifications of MOF metamodels and metamodel transformations in the metamodeling language NEREUS that can be used to connect them with different
formal and programming languages (Favre, 2006) (Favre, 2009).
To sum up, in the level of models, instances of ISMs, PSMs and PIMs are generated by applying
static and dynamic analysis. Static analysis builds an abstract model of the state and determines how
the program executes to this state. Dynamic analysis operates by executing a program and evaluating
the execution trace of the program. Contracts based on MOF-metamodels control the consistency of
these transformations and NEREUS facilitates the connection of the metamodels and transformations
with different formal languages.
Our work could be considered as an MDA-based formalization of the process described by Tonella
and Potrich (2005). Additionally, we propose algorithms for extracting UML diagrams that can differ
on the ones proposed by the mentioned authors. For instance, a different algorithm for extracting State
Diagrams is proposed. We also propose to include OCL specifications (preconditions, postconditions
and invariants) in UML Diagrams. Other advantages are linked to the automation of the formalization
205
process and interoperability of formal languages (Favre, 2007) (Favre, 2008a) (Favre, 2008b) (Favre,
Martinez & Pereira, 2009).
The following sections describe reverse engineering at three different levels of abstraction corresponding to code-to-model transformation, MOF-metamodel formalization and algebraic formalization.
cOde-tO-MOdeL tranSFOrMatiOnS
At model level, transformations are based on static and dynamic analysis. Static analysis extracts static
information that describes the structure of the software reflected in the software documentation (e.g., the
text of the source code) while dynamic analysis information describes the structure of the run-behavioral.
Static information can be extracted by using techniques and tools based on compiler techniques such
as parsing and data flow algorithms. On the other hand, dynamic information can be extracted by using
debuggers, event recorders and general tracer tools.
We suppose that the reverse engineering process starts from the ISM that reflects the migration of
legacy code to object-oriented code. The next step in the migration towards MDA is the introduction of
PSMs. Then, a PIM is abstracted from the PSMs omitting platform specific details.
Next, we describe the process for recovery PSMs from code. Figure 2 shows the different phases. The
source code is parsed to obtain an abstract syntax tree (AST) associated with the source programming
language grammar. Then, a metamodel extractor extracts a simplified, abstract version of language that
ignores all instructions that do not affect the data flows, for instance all control flows such as conditional
and loops.
206
The information represented according to this metamodel allows building the data-flow graph for a
given source code, as well as conducting all other analysis that do not depend on the graph. The idea is to
derive statically information by performing a propagation of data. Different kinds of analysis propagate
different kinds of information in the data-flow graph, extracting the different kinds of diagrams that are
included in a PSM.
The static analysis is based on classical compiler techniques (Aho, Sethi & Ullman, 1985) and abstract interpretation (Jones & Nielson, 1995). On the one hand, data-flow graph and the generic flow
propagation algorithms are specializations of classical flow analysis techniques (Aho, Sethi & Ullman,
1985). Because there are many possible executions, it is usually not reasonable to consider all state
of the program. Thus static analysis is based on abstract models of the program state that are easier to
manipulate, although lose some information. Abstract interpretation of program state allows obtaining
automatically as much information as possible about program executions without having to run the
program on all input data and then ensuring computability or tractability. These ideas were applied in
compiler optimizations. They require information about program semantics and are semantics- preserving program transformations.
In our context, an abstract interpretation performs method invocation using abstract domains instead
of concrete attribute values to deduce information about the object computation on its actual state from
the resulting abstract descriptions of its attributes. This implies to abstract equivalence classes grouping
attribute values corresponding to the different states in which the class can be.
The static analysis builds a partial PSM that must be refined by dynamic analysis. Ernst (2003) provides a comparison of static and dynamic analysis from the point of view of their synergy and duality.
He argues that static analysis is conservative and sound. Conservatism means reporting weak properties
that are guaranteed to be true, preserving soundness, but not be strong enough to be useful. Soundness
guarantees that static analysis provides an accurate description of the behavior, no matter on what input
or in what execution environment. Dynamic analysis is precise due to it examines the actual run-time
behavior of the program. However the results of executions may not generalize to other executions.
Ernst (2003) argues that whereas the chief challenge of static analysis is choosing a good abstract
interpretation, the chief challenge of performing good dynamic analysis is selecting a representative set
of test cases. A test can help to detect properties of the program, but it can be difficult detect whether
results of a test are true program properties or properties of a particular execution context.
Dynamic analysis is based on testing and profiling. Execution tracer tools generate execution model
snapshots that allow us to deduce complementary information. Execution models, programs and UML
models coexist in this process. An object-oriented execution model has the following components: a set
of objects, a set of attributes for each object, a location for each object, each object refers to a value of
an object type and, a set of messages that include a name selector and may include one or more arguments. Additionally, types are available for describing types of attributes and parameters of methods or
constructors. On the other hand, an object-oriented program model has a set of classes, a set of attributes
for each class, a set of operations for each class, and a generalization hierarchy over classes.
The static analysis is based on program models but dynamic analysis is based on execution models.
For instance a basic algorithm for the recovery of class diagram can be obtained by a static analysis.
From the source code, associations, generalization, realizations and dependencies may be inferred. But,
to distinguish between aggregation and composition, or to include OCL specifications (e.g. preconditions and postconditions of operations, invariants and association constraints) we need to capture system
states through dynamic analysis.
207
Dynamic analysis allows generating execution snapshot to collect life cycle traces of object instances
and reason from tests and proofs. The combination of static and dynamic analysis can enrich reverse
engineering process. There are different ways of combination, for instance performing first static analysis
and then dynamic one or perhaps iterating static and dynamic analysis.
The ideas of transformations at model level are based on techniques described in (Tonella & Potrich,
2005). The underlying algorithms to these techniques deal with reverse engineering of UML diagram
from object-oriented code, e.g., Java, Eiffel and C++. The following UML diagrams are considered:
class diagram, interaction diagram (sequence and collaboration diagram), object diagram, state diagram
and package diagram.
Classical compiler techniques such as parsing and data flow are integrated in a common analysis
framework that is shared by all recovering processes. The basic idea is that information is derived statically
by performing a propagation of data. Different kinds of analysis propagate different kind of information
in a dataflow graph. This is built by parsing the source code described by a grammar.
The remaining parts of the chapter describe how to recover UML diagrams from source objectoriented code.
Static analysis
The concepts and algorithms of data flow analysis described in (Aho, Sethi & Ullman, 1985) are adapted
for reverse engineering object oriented code. The data flow analysis can be viewed as the transmission
of useful relationships from all parts of the code to the places when the information can be used.
The basic representation of the static analysis is the Data Flow Graph (OFG) that allows tracing
information of object interactions from the object creation, through object assignment to variables, the
storage of objects in attributes or their use in messages (method invocations). OFG is defined as an
oriented graph that represents all data flows linking objects.
The static analysis is data flow sensitive, but control flow insensitive. This means that programs with
different control flows and the same data flows are associated with the same analysis results (Tonella
& Potrich, 2005).
A consequence of the control flow insensitivity is that the construction of the OFG can be described
with reference to a simplified, abstract version of the object-oriented languages in which instructions
related to flow control are ignored. A generic algorithm of flow propagation working on the OFG processes object information. Then, the three essential components of the common analysis framework are
the simplified abstract object-oriented language, the data flow graph and the flow propagation algorithm.
Following, we describe them.
208
::=
D*S*
(2)
::=
(3)
m (p1,p2,,pj)
(4)
cons (p1,p2,,pj)
::=
x = new c (a1,a2,aj)
(6)
x=y
(7)
[x = ] y.m (a1,a2,,aj)
(5)
A program P consists of zero or more declarations (D*) concatenated with zero or more statements
(S*). The order of declarations and instructions is irrelevant. The nesting structure of packages, classes
and statements is flattened, i.e. statements belonging to different methods are merged and identified by
their fully scope names. The process of transformation of an object oriented program into a simplified
language can be easily automated.
Table 2 shows three types of declaration production: attribute declarations (2), method declarations
(3) and constructor declaration (4). An attribute declaration is defined by the scope determined by the
list of packages, classes, followed by the attribute identifier. A method declaration consists in its name
followed by a list of formal parameter (p1, p2, pj). Constructors have a similar declaration.
Table 2 also shows three types of statement production: allocation statements (5), assignments (6)
and method invocation (7). The left hand side and the right hand side of all statements is a program location. The target of a method invocation is also a program location. Program locations are either, local
variables, class attributes or method parameters.
209
::=
D*S*
{}
(2)
::=
{}
(3)
m (p1,p2,,pj)
{}
(4)
cons (p1,p2,,pj)
{}
::=
x = new c (a1,a2,aj)
(5)
(6)
x=y
{(y,x) E}
(7)
[x = ] y.m (a1,a2,,aj)
and the value returned by method m (if any) flows to the left hand side x (pair (m.return, x)) (Tonella
& Potrich, 2005, pp. 26).
Some edges in the OFG may be related to the usage of library classes. Each time a library class
introduces a data flow from a variable x to a variable y an edge (x,y) must be included in the OFG.
Containers are an example of library classes that introduce external data flows. For instance, any Java
class implementing the interface Collection or the interface Map, or any Eiffel class reusing Container
introduces external data flows.
Object containers provide two basic operations affecting the OFG: insert and extract for adding an
object to a container and accessing an object in a container respectively. In the abstract program representation insertion and extraction methods are associated with container objects.
The OFG treats the two cases:
c.insert (y) and y =c. extract () where c is a container and x is an object. These statements introduce
the edges shown in Table 4 to the OFG.
Other cases require that data flows are modeled semi-automatically in a similar way as done for
the class libraries, for instance dynamic loading and the access to code written in other programming
languages.
210
c.insert(x)
(x,c) E
x = c.extract ()
(c,x) E
211
dynamic analysis
Integrating dynamic and static analysis seems to be beneficial. For instance, the static analysis is not
enough to determine the actual method invocations due to polymorphism. This is only possible by analyzing the behavior. The static and dynamic information could be shown as separated views or merged in a
single view. In general, the dynamic behavior could be visualized as a scenery diagram which describes
interaction between objects. To extract specific information, it is necessary to define particular views
of these sceneries. Although, the construction of these views can be automated, their analysis requires
some manual processing in most cases. In order to describe an integration of static and dynamic analysis
we define the syntax at levels of execution scenery models and object-oriented programs.
a set of objects
a set of attributes for each object
a location for each object
each object refers to a value of an object type
a set of messages
Additionally, types such as Integer, String, Real and Boolean are available for describing types of
attributes and parameters of methods or constructors. For naming elements, we assume an alphabet A
and a set of finite, non-empty of identifiers N A+ over alphabet A. All identifiers are given fully scope
name, being preceded by a dot separated list of enclosing elements.
Objects are associated with attribute values describing properties of the objects that define their state.
All attributes have different names.
A message includes a name selector and may include one or more arguments. Normally, there exist
a determined number of arguments. The acceptable values of arguments belong to a type, not necessarily basic.
a set of classes
a set of attributes for each class
a set of operations for each class
a generalization hierarchy over classes
Additionally, types such as Integer, String, Set (Real) are available for describing types of attributes
and operation parameters.
We assume that there is a signature = (T, O) with T being a set of type names, and O being a set of
operations over types in T.
212
Classes
The central concept of OO programs is the class. A class is a static concept that provides a common
description for a set of objects sharing the same properties.
The set of classes is a finite set of names CLASS N. Each class c CLASS induces an object type
tc T having the same name of the class.
Attributes
Attributes are part of a class declaration. An attribute has a name and a type specifying the domain of
attribute values. Let t T be a type. The attributes of a class have distinct names. Attributes with the
same name may, however, appear in different classes that are not related by generalization. The set of
attribute names and class names need not be disjoint.
Operations
Operations are part of a class definition. They are used to describe behavioral properties of objects.
Operations of a class c CLASS with tc T are defined by a set OPc of signatures w: tc x t1 x x tn
-> t with operation symbols w being elements of N.
The name of an operation is determined by the symbol w. The first parameter tc denotes the type of
the class instance to which the operation is applied. An operation may have any number of parameters
but only a single return type.
Generalization
A generalization is a taxonomic relationship between two classes. This relationship is a specialization
of a general class into a more specific class. Specialization and generalization are different views of the
same concept. Generalization relationships form a hierarchy over a set of classes.
A child class implicitly inherits attributes and operation of its parent class. It contains all inherits
attributes and operations of its parent classes. It contains all inherited attributes (and operations) and
those that are defined directly in the class.
Dynamic analysis allows producing specifications in OCL or detecting specific relationships such
as composition. Nimmer and Ernst (2002) investigate combining dynamic and static analysis for recovering formal specifications. They propose to generate specifications from program executions, then
verify them, i.e., to dynamically detect and then statically verify program specifications. They suggest
that dynamic analysis can capture all semantics information of interest in certain applications. Their
experimental results demonstrate that a specific technique, dynamic invariant detection, is effective at
generating consistent specifications that can be used by a static checker. Recovering specifications is
useful in testing, debugging, verification, maintenance and optimizations. These ideas can be adapted
for recovering OCL specifications in MDA models.
Now, we are in the situation to analyze reverse engineering of UML diagrams from object-oriented
code. First, we analyze code to model transformations for two classical diagrams: Class Diagram and
State Diagram.
213
type-anti-symmetry: the aggregation from a type A (as whole) to a type B (as part), prevents the
existence of another aggregation from B (as a whole) to A (as part)
instance-reflexivity
instance anti-symmetry
Dynamic analysis allows generating execution snapshot to collect life cycle traces of object instances
and reason from tests and proofs. Execution tracer tools generate execution model snapshots that allow
us to deduce complementary information.
Execution models, programs and UML models coexist in this process. An object-oriented execution
model has the following components: a set of objects, a set of attributes for each object, a location for
each object, each object refers to a value of an object type and, a set of messages that include a name
selector and may include one or more arguments. Additionally, types are available for describing types
of attributes and parameters of methods or constructors. On the other hand, an object-oriented program
model has a set of classes, a set of attributes for each class, a set of operations for each class, and a
generalization hierarchy over classes.
A composition is a particular aggregation in which the lifetime of the part is controlled by the whole
(directly or transitively). Then, we can detect a composition by generating tests and scanning dependency
configurations between the birth and the death of a part object according to those of the whole.
214
In the same way, the execution traces of different instances of the same class or method, could guide
the construction of invariants or pre- and post-conditions respectively.
215
group attribute values corresponding to the different states in which the class can be and the transitions
among state equivalence classes.
Then, the first step is to define an appropriate abstract interpretation for attributes (which give the
state of the object) and transformer class method (which give the transitions from state to state to be
represented in the state diagram).
A taxonomy of finite-state automata minimization can be found at (Watson, 1995) and (Daciuk, 1998).
The main characteristic of these algorithms is that they are incremental. The minimization algorithm
should compare incrementally the equivalence between pairs of states to determine whether they can
be merged in an only state.
The recovery algorithm iterates over the following activities: the construction of a finite automata by
executing abstract interpretations of class methods and the minimization of the automata for recovering
approximate state equivalence classes.
To ensure tractability, our algorithm proposes an incremental minimization every time a state is
candidate to be added to the automaton. When it is detected that two states are equivalents, they are
merged in an only state. This could lead to modification of the parts of the automaton that had been
previously minimized. To optimize the comparison of pairs of states, these are classified according to
their emerging transitions. Let m be a bound of the number of transformer methods of a class, the idea
is to generate subsets of the set of transformer methods. The subset of emerging transitions of a new
state belongs, in a particular snapshot, to one of them. Two states are candidates to be equivalent if they
belong to the same subset. Then, it is sufficient to compare all the pairs composed by the state and one
element of the subset. Considerable human interaction to select which abstract interpretations should
be executed is required. Then, our approach is so significantly less automatic than traditional abstract
interpretation (Nielsen & Jones, 1995).
As an example, Figure 4.a shows a diagram including states (s1, s2,.., s8) and transitions (m1,m2,
,m6). Figure 4.b shows a simplified snapshot of the automaton when a transition to s5 is added. Then,
the shaded states could belong to the same equivalence state class. s8 belongs to the same subset of s4
and an equivalence analysis is carried out concluding that s8 and s4 can be merged (Figure 4.c, Figure
216
4.d) . Figure 4.e shows the successive transformations. Next, we show the pseudo code of the recovery
algorithm.
Algorithm for recovering State Diagrams
-- initialization of different sets
set-of-states initialStates = {}; -- states defined by class constructors
set-of-states pendingStates ={};-- set of states pending of analysis
set-of-states allStates = {};-- set of all states
--definition of initial states for the objects of the class
for each class constructor c
{-- executing an abstract interpretation of each class constructor
state s = abstractInterpretationState (c, {});
initialStates = initialStates {s};
pendingStatesPending = pendingStates {s};
allStates = allStates {s};
}
-- initialization of transition set
set-of-transitions transitionSet = {};
-- generation of subsets of transformer methods
set-of-bins b = classifiedStates (allStates);
while |pendingStates| > 0
{ state r = extract (pendingStates);
pendingState = pendingStates {r};
for each transformer class method m
{-- generating transitions of the state r
s = abstractInterpretationState (m, r);
if s allStates
{pendingStates = pendingStates {s};
allStates = allStates {s};}
transitionSet = transitionSet abstractInterpretationTransition (m,r,s);}
-- updating subsets of transformer methods
b = modifyBins (r, transitionSet, allStates);
for each e b
if s b
{-- defining equivalence of states and merging equivalent
states
for each q bin and s< > q
217
218
Figure 7 shows partially a PSM-Java metamodel that includes constructs for representing classes,
field, operations and association-end. It also shows different kind of relationships such as composition
and generalization. For example, an instance of JavaClass could be related to another instance of JavaClass that takes the role of superclass or, it could be composed by other instances of JavaClass that
takes the role of nestedClass. The main difference between a Java-ISM and a Java-PSM is that the latter
includes constructs for associations.
Metamodel transformations impose relations between a source metamodel and a target metamodel, both
represented as MOF-metamodels. The transformations between models are described starting from the
metaclass of the elements of the source model and the metaclass of the elements of the target model. The
models to be transformed and the target models will be instances of the corresponding metamodel.
The transformation specification is an OCL contract that consists of a name, a set of parameters, a
precondition and postconditions. The precondition states relations between the metaclasses of the source
metamodel. The postconditions deal with the state of the models after the transformation. Next, an antirefinement between an ISM-Java (Figure 5) and a PSM-Java (Figure 7) is partially specified.
219
220
221
Context PseudoState
--An initial vertex can have at most one ongoing transition (self.
kind = #initial) implies (self.outgoing -> size <= 1)
Context Region
--A region can have at most one initial vertex. self.subvertex ->
select (v |v.oclIsKindOf (Pseudostate)) -> select (p:Pseudostate
|p.kind = #initial) -> size () <=1
With respect to reverse engineering processes, two types of consistency can be distinguished, vertical consistency between different levels of refinements and horizontal consistency or inter-consistency
between models at the same abstraction level. For instance, a vertical consistency analysis detects when
a state model is associated to a class that does not exist in the ISM. A horizontal consistency analysis
could detect that the sequence of interactions shown in the sequence diagram does not exist as a trace
of the state diagram linked to the respective class. We propose to specify consistency relationships as
OCL contracts based on MOF- metamodels.
Next, we partially exemplify a transformation from an ISM-Java (Figures 5 & 6) to a PSM-Java
(Figure 7). This transformation uses both the specialized UML metamodel of Java code and the UML
metamodel of a Java platform as source and target parameters respectively. The postconditions state
relations at metamodel level between the elements of the source and target model. The transformation
specification guarantees that for each class in Java code there is a class in the PSM-Java, both of them
with the same name, the same parent class, equivalent operations and so on. Besides, the PSM-Java has
a stateMachine for each class having a significant dynamic behavior.
Transformation ISM-JAVA to PSM-JAVA {parameter
sourceModel: ISM-JAVA-Metamodel:: JavaPackage
targetModel: PSM-JAVA-Metamodel:: JavaPackage
postconditions
-- For each class sourceClass in the sourceModel
sourceModel.ownedMember -> select (oclIsTypeOf (JavaClass)) ->
forAll (sourceClass |
--there is a class targetClass in the targetModel so that both
classes have the same
--name,
targetModel.ownedMember -> select (oclIsTypeOf (JavaClass)) ->
exists (targetClass | targetClass.name = sourceClass.name and
-- if sourceClass has an extends relation, targetModel has a superclass so that
-- both superclasses are equivalent.
sourceClass.extends -> size () = 1 implies (targetClass.superClass
-> size () = 1 and targetClass.superClass.classMatch(sourceClass.
extends)) and
--For each operation of sourceClass there is an operation in targetClass so that
222
223
END-PACKAGE
Anti-refinements are specified as links between metamodels, where OCLexp1 and OCLexp2 are
the precondition and postconditions in a transformation respectively. Instances of metamodel-based
transformations are automatically translated into NEREUS specifications by instantiating the following
reusable scheme:
CLASStransformationName [source: Metamodel_A; target: Metamodel_B]
GENERATED-BY addLink
EFFECTIVE
TYPEtransformationName
OPERATIONS
addLink: source x target -> metaLink
pre: Translate NEREUS (Transformation_AtoB. Precondition)
getSource: metamodelLink -> source
getTarget: metaLink -> target
AXIOMS m1: source ; m2: target ; l: transformationName
getSource (addLink(m1,m2)) = m1
getTarget (addLink (m1,m2)) = m2
Translate NEREUS (Transformation.Postcondition)
END-CLASS
The function TranslateNEREUS (transformation.precondition) that appears in the transformation scheme
as a precondition of the operation addLink translates into NEREUS precondition the OCL precondition. The function TranslateNEREUS (transformation.postcondition) that appears in the axioms translates
into NEREUS axioms the OCL postconditions. An instantiation of the transformation scheme is the
following:
[TransformationName: ISMJava to PSMJava;
sourceMetamodel: ISM -JAVA-Metamodel:: JavaPackage;
targetMetamodel: PSM -JAVA-Metamodel:: JavaPackage ;
precondition: OCLexp1;
postcondition: OCLexp2 ]
225
reFerenceS
Aho, A., Sethi, R., & Ullman, J. (1985). Compilers: Principles, Techniques, and Tools (2nd ed.). Reading: Addison-Wesley.
Amstrong, M., & Trudeau, C. (1998) Evaluating architecture extractors. In Proceedings of the 5th Working Conference on Reverse Engineering (WCRE 98). Honolulu, Hawaii, USA (pp. 30-39).
Angyal, L., Lengyel, L., & Charaf, H. (2006). An Overview of the State-of-the-Art Reverse Engineering
Techniques. In Proceedings of the 7th International Symposium of Hungarian Researchers on Computational Intelligence (pp. 507 - 516).
Antoniol, G., Fiutem, R., Lutteri, G., Tonella, P., & Zanfei, S. (1997) Program understanding and
mintenance with the CANTO environment. In Proceedings of the International Conference on Software
Maintenance. Bari, Italy (pp. 72-81)
Bellay, B., & Gall, H. (1998). An evaluation of reverse engineering tool capabilities. Journal of Software Maintenance: Research and Practice, 10, 305331. doi:10.1002/(SICI)1096-908X(199809/10)10:5<305::AIDSMR175>3.0.CO;2-7
Boronat, A., Carsi, J., & Ramos, I. (2005). Automatic reengineering in MDA using rewriting logic a
transformation engine. In Proceedings of the Ninth European Conference on Software Maintenance and
Reengineering (CSMR05) (pp. 228-231). Los Alamitos: IEEE Computer Society.
Canfora, G., & Di Penta, M. (2007). New Frontiers of reverse Engineering. Future of Software engineering. In Proceedings of Future of Software Engineering (FOSE 2007) (pp. 326-341). Los Alamitos:
IEEE Press.
CASE. (2009). CASE Tools. Retrieved on July 20, 2009 from www.objectsbydesign.com/tools/umltools_byCompany.html
Chen, Y., Nishimoto, M., & Ramamoorthy, C. (1990). The C information abstraction system. IEEE
Transactions on Software Engineering, 16(3), 325334. doi:10.1109/32.48940
Daciuk, J. (1998). Incremental Construction of Finite-State Automata and Transducers, and their use
in the Natural Language Processing. Ph. D. Thesis. Technical University of Gdansk.
Deissenboeck, F., & Ratiu, D. (2006). A Unified Meta Model for Concept-Based Reverse Engineering.
In Proceedings of 3rd International Workshop on Metamodels, Schemes, Grammars, and Ontologies
for Reverse Engineering. Retrieved on July 20, 2009 from http://planet-mde.org/atem2006/atem06Proceedings.pdf
Demeyer, S., Ducasse, S., & Nierstrasz, O. (2002). Object-Oriented Reengineering Patterns. Amsterdam:
Morgan Kaufmann.
Dwyer, M., Hatcliff, J., Joehanes, R., Laubach, S., & Pasareanu, C. Robby, Zheng, H., & Visser, W.
(2001). Tool-supported program abstraction for finite-state verification. In Proceedings of the International Conference on Software Engineering (pp. 177-187).
226
Eclipse (2009). The eclipse modeling framework. Retrieved from July 20, 2009 from http://www.eclipse.
org/emf/
Ernst, M. (2003) Static and Dynamic Analysis: Synergy and duality. In Proceedings of ICSE Workshop
on Dynamic Analysis (WODA 2003) (pp. 24-27).
Fanta, R., & Rajlich, V. (1998). Reengineering object-oriented code. In Proceedings of International
Conference on Software Maintenance (pp. 238-246). Los Alamitos: IEEE Computer Society.
Favre, L. (2006). A Rigorous Framework for Model Driven Development. In K. Siau (Ed.), Advanced
Topics in Database Research, Vol. 5 (pp. 1-27). Hershey, PA: Idea Group Publishing.
Favre, L. (2008a). Formalizing MDA-based Reverse Engineering Processes. In Proceedings of the 6th
ACIS International Conference on Software Engineering Research, Management and Applications, SERA
2008 (pp. 153-160). Los Alamitos: IEEE Computer Society.
Favre, L. (2008b). Modernizing Software & System Engineering Processes. In Proceedings of the 19th International conference on System Engineering (pp. 442-447). Los Alamitos: IEEE Computer Society.
Favre, L., Martinez, L., & Pereira, C. (2009). MDA-based Reverse Engineering of Object-Oriented Code.
Lecture Notes in Business Information Processing, 29 (pp. 251-263). Heidelberg: Springer-Verlag.
Favre, L., Pereira, C., & Martinez, L. (2009). Foundations for MDA CASE Tools. In M. Khosrow-Pour
(Ed.) Encyclopedia of Information Science and Technology, Second Edition. (pp. 159 166). Hershey,
PA: IGI Global.
Finnigan, P., Holt, R., Kalas, I., Kerr, S., Kontogiannnis, K., & Muller, H. (1997). The software bookshelf. IBM Systems Journal, 36(4), 564593.
Greevy, O., Ducasse, S., & Girba, T. (2005). Journal of Software Maintenance and Evolution . Research
and Practice, 18(6), 425456.
Gueheneuc, Y. (2004) A Systematic Study of UML Class Diagram Constituents for their Abstract and
Precise Recovery. In Proceedings of 11th Asia-Pacific Software Engineering Conference (APSEC 2004)
(pp. 265-274). Los Alamitos: IEEE Computer Society.
IMAGIX4D (2000) Imagix Corp. Retrieved from http://www.imagix.com
Jones, N., & Nielson, F. (1995). Abstract interpretation: A semantic based tool for program analysis. In
D. Gabbay, S. Abramsky, & T. Maibaum (Eds), Handbook of Logic in Computer Science (Vol. 4, pp.
527-636). Oxford: Clarendon Press.
Kagdi, H., Collard, M. L., & Maletic, J. (2007). A survey and taxonomy of approaches for mining software repositories in the context of software evolution. Journal of Software Maintenance and Evolution:
Research and Practice, 19, 77131. doi:10.1002/smr.344
Kazman, R., & Carriere, S. (1999). Playing detective: reconstructing software architecture from available evidence. Journal of Automated Software Engineering, 6(2), 107138. doi:10.1023/A:1008781513258
227
Koehler, J., Hauser, R., Kapoor, S., Wu, F., & Kumaran, S. (2003). A model-driven transformation
method. In . Proceedings of Seven IEEE Enterprise Distributed Object Computing Conference, EDOC,
2003, 186197. doi:10.1109/EDOC.2003.1233848
MacDonald, A., Russell, D., & Atchison, B. (2005). Model driven Development within a Legacy System:
An industry experience report. In Proceedings of the 2005 Australian Software Engineering Conference
(ASWEC 05) (pp. 14-22). Los Alamitos: IEEE Press.
Mansurov, N., & Campara, D. (2005). Managed architecture of existing code as a practical transition
towards MDA (LNCS 3297, pp. 219-233). Heidelberg: Springer-Verlag.
Markosian, L., Newcomb, P., Brand, R., Burson, S., & Kitzmiller, T. (1994). Using an enabling technology to
reengineer legacy systems. Communications of the ACM, 37(5), 5870. doi:10.1145/175290.175297
MDA. (2005). The Model Driven Architecture. Retrieved on July 20, 2009 from www.omg.org/mda.
MetaEdit. (2009) MetaEdit++. Retrieved on July 20, 2009 from http://www.metacase.com/MetaEdit.
html
MOF. (2006). MOF: Meta Object facility (MOF ) 2.0. OMG Specification formal/2006-01-01. Retrieved on July 20, 2009 from www.omg.org/mof
Muller, H., & Klashinsky (1988). Rigi- A System for programming in the large. In Proceedings of the
10th International Conference on Software Engineering (ICSE) (pp. 80-86). Los Alamitos: IEEE Computer Society Press.
Muller, H., Jahnke, J., Smith, D., Storey, M., Tilley, S., & Wong, K. (2000). Reverse Engineering: A
Roadmap. In Proceedings of the 22nd International Conference on Software Engineering (ICSE 2000),
Limerick, Ireland. ACM Press. Retrieved on July 20, 2009 from http://www.cs.ucl.ac.uk/staff/A.Finkelstein/fose/finalmuller.pdf
Nimmer, J., & Ernst, M. (2002) Automatic generation of program specifications. In Proceedings of the
2002 International Symposium on Software Testing and Analysis (pp. 232-242). Rome, Italy.
OCL. (2006). OCL: Object Constraint Language. Version 2.0. OMG: formal/06-05-01.Retrieved on
July 20, 2009 from www.omg.org
Pohyvanyk, D., Gueheneuc, Y.-G., Marcus, A., Antoniol, G., & Rajlich, V. (2007). Feature Location
Using Probabilistic ranking of Methods Based on Execution Scenarios and Information Retrieval. IEEE
Transactions on Software Engineering, 23(6), 420432. doi:10.1109/TSE.2007.1016
Qiao, B., Yang, H., Chu, W., & Xu, B. (2003). Bridging legacy systems to model driven architecture. In
Proceedings of 27th Annual International Computer Aided Software and Applications Conference (pp.
304-309). Los Alamitos: IEEE Press.
Reus, T., Geers, H., & van Deursen, A. (2006). Harvesting Software System for MDA-based Reengineering (LNCS 4066, pp. 220-236). Heidelberg: Springer-Verlag.
SNiFF+ (1996) SNiFF+. User Guide and Reference, Take-Five Software. Retrieved on July 20, 2009
from www.takefive.com
228
Suny, G., Pollet, D., LeTraon, D., & Jzquel, J. (2001). Refactoring UML Models (LNCS 2185, pp.
134-138). Heidelberg: Springer-Verlag.
Systa, T. (2000). Static and Dynamic Reverse Engineering Techniques for Java Software Systems. Ph.D
Thesis, University of Tampere, Report A-2000-4.
Tonella, P., & Potrich, A. (2005). Reverse Engineering of Object Oriented Code. Monographs in Computer Science. Heidelberg: Springer-Verlag.
UML. (2009a). Unified Modeling Language: Infrastructure. Version 2.2. OMG Specification formal/2009-02-04. Retrieved on July 20, 2009 from www.omg.org.
UML. (2009b). UML: Unified Modeling Language: Superstructure. Version 2.2. OMG Specification:
formal/2009-02-02. Retrieved on July 20, 2009 from www.omg.org
Watson, B. (1995). Taxonomies and Toolkits of Regular Language Algorithms. PhD thesis. Eindhoven
University of Technology, The Netherlands.
229
Section 4
Conclusions
231
Chapter 11
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
MDA distinguishes at least three main models: Computation Independent Model (CIM), Platform Independent Model (PIM), Platform Specific Model (PSM) and Implementation Specific Model (ISM).
The initial diffusion of MDA was focused on its relation with UML as modeling language. However,
there are UML users who do not use MDA, and MDA users who use other modeling languages such as
DSLs. The essence of MDA is MOF that allows different kinds of artifacts from multiple vendors to be
used together in a same project.
MOF-metamodels are expressed as a combination of UML, OCL and natural language. MOF has no
built-in semantics apart from the well-formedness rules in OCL and what can deduced from them. This
form of specification does not make possible validating that specific metamodels, like UML metamodel,
conform MOF. A combination of MOF metamodeling and formal specification can help us to address
MDA reverse engineering process.
With the emergence of MDA, new approaches should be developed in order to reverse engineering,
both platform independent and platform specific models, from object oriented code.
This book describes MDA reverse engineering processes based on the integration of traditional reverse
engineering techniques, advanced metamodeling techniques and formal specification. A framework to
reverse engineering MDA models from object oriented code that distinguishes three different levels of
abstraction linked to models, metamodel and formal specification was proposed.
The model level includes code, PIMs and PSMs. A PIM is a model with a high level of abstraction
that is independent of an implementation technology. A PSM is a tailored model to specify a system in
terms of specific platform such J2EE or .NET. PIMs and PSMs are expressed in UML and OCL. The
subset of UML diagrams that are useful for PSMs includes class diagram, object diagram, state diagram,
interaction diagram and package diagram. On the other hand, a PIM can be expressed by means of use
case diagrams, activity diagrams, interactions diagrams to model system processes and state diagrams
to model lifecycle of the system entities. An ISM is a specification of the system in source code.
At model level, transformations are based on classical compiler construction techniques. They involve
processes with different degrees of automation, which can go from totally automatic static analysis to
human intervention requiring processes to dynamically analyze the resultant models. All the algorithms
that deal with the reverse engineering share an analysis framework. The basic idea is to describe source
code or models by an abstract language and perform a propagation analysis in a data-flow graph called,
in this context, object-data flow. This static analysis is complemented with dynamic analysis supported
by tracer tools.
The metamodel level includes MOF metamodels that describe the transformations at model level.
MOF metamodels describe families of ISMs, PSMs and PIMs. Every ISM, PSM and PIM conforms to
a MOF metamodel. Metamodel transformations are specified as OCL contracts between a source metamodel and a target metamodel. These contracts control the transformation consistency.
This book describes a formalization of MDA processes in terms of MOF-based metamodels and
QVT-based transformations. Both, MOF and QVT, depends on UML metamodel, which in turn depends
on OCL. That is to say, the formalization of MDA processes depends on various OMG standards. Some
of them, such as OCL and QVT, involve imperative constructions that are hard to formalize. To avoid
this inconvenient, we analyzed the graph of package dependencies to select a minimal set of packages
that allows us to precisely define the semantics of MDA process in a way independent of imperative
constructions. . The formalization is based on a subset of OMG standard metamodels that we called MDA
Infrastructure, including elements of UML Infrastructure, EssentialOCL, EMOF and the QVT-Core.
232
The level of formal specification includes specifications of MOF metamodels and metamodel transformations in the metamodeling language NEREUS that can be used to connect them with different formal
and programming languages. NEREUS, like MDA, was designed for improving interoperability and
reusability through separation of concerns. It is suited for specifying metamodels based on the concepts
of entity, associations and systems. Formal specification can be automatically generated by using reusable schemes and a system of transformation rules for translating OCL specification into NEREUS.
We analyze how to define reusable components in a way that fits with MDA and propose a megamodel
for defining MDA components. Considering the relevant role that design patterns take in software evolution we exemplify MDA components for them. We propose a megamodel to define families of design
pattern components by means of PIM-, PSM- and ISM-metamodels and their interrelations. Instances
of the megamodel are reusable components that describe specific design patterns at different levels
of abstraction (PIMs, PSMs and ISMs). They can be viewed as megacomponents that allow defining
in a concise way as many components as different pattern solutions can appear.
In MDA is crucial to define, manage, and maintain traces and relationships between different models,
and automatically transform them and produce implementations. Refactoring is a powerful technique
when is repeatedly applied to a model to obtain another one with the same behavior but enhancing
some non functionality quality factor such as simplicity, flexibility, understandability and performance.
Refactorings are horizontal transformations for supporting perfective model evolution. We propose
an MDA framework for refactoring that is structured at three different levels of abstraction linked to
models, metamodels and formal specification. The model level includes different kind of models (PIM,
PSM, ISM) related by refinement.
Our approach to MDA processes has two main advantages linked to automation and interoperability.
On the one hand, our approach shows how to generate automatically formal specifications from MOF
metamodels. On the other hand, our approach focuses on interoperability of formal languages. Considering that there exist many formal algebraic languages, NEREUS allows any number of source languages
such as different DSLs and target languages (different formal language) could be connected without
having to define explicit metamodel transformations for each language pair. Such as MOF is a DSL to
define semi-formal metamodels, NEREUS can be viewed as a DSL for defining formal metamodels.
Another advantage of our approach is linked to pragmatic aspects. NEREUS is a formal notation
closed to MOF metamodels that allows meta-designers who must manipulate metamodels to understand
their formal specification.
Our approach could be considered as an MDA-based formalization of traditional reverse engineering processes. The underlying ideas contribute to a more general goal, the definition of rigorous MDA
processes such as forward engineering, reverse engineering and in general round trip engineering.
This book intends to shorten the path to this goal providing an overview of several techniques that
can be adopted in the field of MDA-based processes. It presents principles of reverse engineering within
system evolution and shows how to recover designs and architectures. Different techniques for helping
in reverse engineering about how to define MDA-based reusable component and transformations are
covered. The underlying concepts were giving with special emphasis on consistency, traceability, testing
and verification combining semiformal metamodeling techniques and formal specification.
Although, this book uses some specific notation, the underlying ideas of our approach are independent of NEREUS and the proposed rule transformational system. The following are the bases of our
approach:
233
234
measuring quality of software reverse engineering, because pattern and anti-pattern can help to discover
weakness of code or models.
MDA approach is useless without tools automating the model transformation. The existing MDAbased tools do not provide sophisticated transformation from PIM to PSM and from PSM to code. To
date, they might be able to support forward engineering and partial round trip engineering between PIM
and code. Little support for reverse engineering business models from code is provided for the existing
CASE tools.
The MDA Case tools must evolve towards a new generation of tools that insure consistency of variety of artifacts representing different dimensions. MDA is an architectural framework for specifying
software artifacts and their interrelations. It allows working with existing tools by abstracting information from the external representation used by them. This abstraction provides independence from the
used tools and should be aligned to OMG standards such as XMI and in general, artifacts represented
by MOF metamodels.
The existing tools should also handle dynamic information. The idea is determine, on the one hand
what information need to be collected at run time, and then checking that the contracts are satisfied when
the program run or, on the other hand inferring constraints that may be added to the artifact specification.
Besides, there is a need to develop tools for new software architecture that have characteristics of being
extremely dynamic, highly distributed, self-configurable and heterogeneous.
To date most MDD research focuses on Software Language Engineering. Perhaps, in the coming
years the focus will be on Software Process Engineering. In the light of the advances, a new type of
tools, that do a more intelligent job, might emerge. Probably, the next generation of tools might be able
to describe the behavior of software systems in terms of business models and translate it into executable
programs on distributed environment and to automate round-trip engineering processes. It will probably take several years before a full round trip engineering based on standards occurs (many authors
are skeptical about this).
235
236
Chapter 12
intrOductiOn
This chapter discusses software evolution, challenges and strategic directions in the context of MDA.
Various authors agreed that it is difficult to define completely software and then, software evolution.
Software is certainly more that bits stored in a file, it is an abstract idea that encompasses the concepts,
algorithms embodied in the implementation as well as all its associated artifacts and processes. Research
seems to confirm that computer software and process software have much in common. Osterweil (2003)
assures that software processes are software too. In other paper (Osterweil, 2007), he suggests analyzing
the nature of software and proposes to define taxonomies for exploring characteristics and approaches
to the development, verification of qualities and software evolution. The exploration of these questions
is an important current of software engineering research.
On the other hand, evolution is defined as a process of gradual change and development from fewer
and simpler forms to higher, more complex, or better ones. In biology, evolution is related to develop
over time often many generations, into forms that are better adapted to survive changes in their environment. Thus, evolution captures the notion of something improving and changes occur in species in successive generations, i.e. individuals get old and species evolve. Jazayeri (2005) analyzes the definition
of software evolution. The concept of specie in software may be associated to meta-levels describing
families (species) of software systems. These meta-levels or architectures are created as improvements
to previous existing ones and describe evolved families of software systems.
Evolution must focus on species of software rather than individual software applications. Then,
Software, like people, get old (Parnas, 1994) and meta-levels or architectures, like species, evolve.
DOI: 10.4018/978-1-61520-649-0.ch012
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
Starting from our understanding of software applications, their specification in terms of models (and
metamodels) evolves to new generation of tools that have an improved structure and are based on new
technologies.
Software evolution is multidimensional and is composed of different types of entities/concepts or
artifacts that come from specifications, designs and architectures to source code, test cases and documentation. Each of them depends on other artifacts embodied in the implementation such as user interfaces,
components, patterns and so on. The different ways and rates that these artifacts change, lead to unreliable software and cause many problems associated with software maintenance.
Software artifacts evolve at different rhythm and in different ways, for instance, an initial design is
not updated to reflect the changes that are introduced in the code. Software evolution needs a software
development framework that supports the consistency evolution of the different dimensions of the
software.
In this light, an MDA-based approach can help to support consistently software evolution due to
MDA can be viewed as an integration architectural framework that maintains consistency as the software
evolves, i.e., the concept of multidimensional evolution is in the essence of MDA.
MDA can help to develop and support a common application framework for software evolution that
raises issues such as common exchange formats, tool integration and interoperability. When the system
evolves, MDA maintains the interrelation between software entities accommodating the evolution of
higher level artifacts together with the code in a consistent way.
Next, we describe challenges in software evolution and the role of MDA to overcome or avoid the
negative effect of software aging.
To provide tools and techniques which preserve or even improve the quality characteristics of a
software system, whatever its size and complexity.
To develop and support a common application framework for doing joint software evolution
research.
Software evolution techniques should be raised to a higher level of abstraction, in order to accommodate not only evolution of programs, but also evolution of higher-level artifacts.
To achieve co-evolution between different types of software artifacts or different representation
of them.
In order to become accepted as practical tools for software developers, formal methods need to
embrace change and evolution as an essential fact of life.
Software evolution must provide more and better support for multi-language systems.
(Mens, Wermelinger, Ducasse, Demeyer, Hirschfeld and Jazayeri, 2005)
A challenge on software evolution is the necessity to achieve co-evolution between different types
of software artifacts or different representations of them. MDA allows us to develop and relate all dif-
237
ferent artifacts in a way that ensures their inter-consistency. MDA raises the level of reasoning to a
more abstract level and therefore even more appropriate. It places change and evolution in the center of
software development process. To give a few examples, in the context of MDA co-evolution is needed
between:
Among others, an interesting research direction would be treat the notion of change in programming
and modeling languages as a first-class entity and provide support for multi language systems.
Existing formal methods provide a poor support for evolving specifications and incremental verification approaches. In particular, with the existing verification tools, simple changes in a system require
to verify its complete specification again making the cost of the verification proportional to its size. To
use formal methods that place change and evolution in the center of the software development process
is another challenge (Canfora & Di Penta, 2007)
Component-based software offers interesting challenges in software evolution. New tools and techniques to analyze the evolution of systems and their components both in a way independent from each
other and as interrelated artifacts must emerge. Perhaps, an interesting challenge would be an MDA
adaptation of existing results for analyzing software evolution through feature views (Pohyvanyk,
Gueheneuc, Marcus, Antoniol and Rajlich, 2007) (Greevy, Ducasse & Girba, 2005). Buckley, Mens
and Zenger (2005) propose taxonomy of software change based on characterizing the mechanisms of
change and the factors that influence these mechanisms. The goal is to relate concrete tools, formalisms
and methods within the domain of software evolution.
The integration of business models with PIM, PSMs and code is crucial to achieve software evolution.
Some works are producing advances in this direction. Hess (2005) describes an approach for mapping
business requirements to application software, for using patterns to help translate business requirements
to software requirements, and for using patterns to translate software requirements into potential solution
designs. Besides, the integration between ontologies (that are essentially CIMs) and MDA is occupying
a central place in software development (Djuric, Gasevic and Devedzic, 2005) (Kherraf, Lefrebe, &
Suryn, 2008).
OMG is involved in the definition of standards to successfully modernize existing information
systems. The OMG Architecture-Driven Modernization (ADM) Task Force is developing a set of modernization standards for the purpose of software improvement, modifications, interoperability, refactoring, restructuring, reuse, porting, migration and MDA migration. Current work involves building a
Knowledge Discovery Meta-model (KDM) to facilitate the exchange of existing systems meta-data for
various modernization tools. Subsequent standards will address analysis, visualization, refactoring and
transformation related standards. A detailed description may be found at ADM (2007).
In summary, a lot remains to be done to provide support for MDA-based software evolution:
238
New verification tools that embrace change and evolution as central in software development
processes
Development of new sophisticated tools to develop industrial size software systems
Definition of standards to evaluate the quality of evolved artifacts/systems.
Besides, the adoption of software evolution should be favored by educating future generations of
software engineers, i.e., integrating background on software evolution into the computer science curriculum.
reFerenceS
Buckley, J., Mens, T., & Zenger, M. (2005). Towards a taxonomy of software change. Journal of Software
Maintenance and Evolution: Research and Practice, 1-26.
Canfora, G., & Di Penta, M. (2007). New Frontiers of reverse Engineering. Future of Software engineering. In Proceedings of Future of Software Engineering (FOSE 2007) (pp. 326-341). Los Alamitos:
IEEE Press.
Djuric, D., Gasevic, D., & Devedzic, V. (2006). Model Driven Architecture and Ontology Development.
Heidelberg: Springer-Verlag.
Greevy, O., Ducasse, S., & Girba, T. (2005). Journal of Software Maintenance and Evolution . Research
and Practice, 18(6), 425456.
Hess, H. (2005). Aligning technology and business: Applying patterns for legacy transformation. IBM
Systems Journal, 44(1), 2545.
Jazayeri, M. (2005) Species evolve, individuals age. In Proceedings of the 2005 Eight International
Workshop on Principles of Software Evolution (IWPSE05) (pp. 3-9). Los Alamitos: IEEE Computer
Society.
Kherraf, S., Lefebre, E., & Suryn, W. (2008). Transformation From CIM to PIM Using Patterns and
Archetypes. In Proceedings of the 19th Australian Conference on Software Engineering (pp. 338-346).
Los Alamitos: IEEE Computer Society.
Mens, T., Wermelinger, M., Ducasse, S., Demeyer, S., Hirschfeld, R., & Jazayeri, M. (2005). Challenges
in Software Evolution. In Proceedings of Eighth International Workshop on Principles of Software
Evolution (pp. 13-22). Los Alamitos: IEEE Computer Society.
Osterweil, L. (2003). Software Processes Are Software Too, Revisited [Los Alamitos: IEEE Computer
Press.]. An Invited Talk on the Most Influential Paper of ICSE, 1997, 540548.
Osterweil, L. (2007) A Future for Software Engineering? In Proceedings of Future of Software Engineering (FOSE 2007) (pp. 1-11). Los Alamitos, IEEE Computer Society
Parnas, D. (1994) Software aging. In Proceedings of the International Conference on Software Engineering (pp. 279-287). Los Alamitos: IEEE Computer Press.
239
Pohyvanyk, D., Gueheneuc, Y.-G., Marcus, A., Antoniol, G., & Rajlich, V. (2007). Feature Location
Using Probabilistic ranking of Methods Based on Execution Scenarios and Information Retrieval. IEEE
Transactions on Software Engineering, 23(6), 420432. doi:10.1109/TSE.2007.1016
240
Section 5
Selected Readings
242
Chapter 13
intrOductiOn
The model driven architecture (MDA) is an
initiative proposed by the object management
group (OMG), which is emerging as a technical
framework to improve productivity, portability, interoperability, and maintenance (MDA, 2003).
MDA promotes the use of models and modelto-model transformations for developing software systems. All artifacts, such as requirement
specifications, architecture descriptions, design
descriptions, and code are regarded as models.
MDA distinguishes four main kinds of models:
computation independent model (CIM), platform
independent model (PIM), platform specific models (PSM), and implementation specific model
(ISM).
A CIM describes a system from the computation independent viewpoint that focuses on the
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
BacKgrOund
To date, there are about 120 UML CASE tools
that vary widely in functionality, usability, performance, and platforms (CASE, 2006). Some of
them can only help with the mechanics of drawing
and exporting UML diagrams. The mainstream
object-oriented CASE tools support forward engineering and reverse engineering processes and
can help with the analysis of consistency between
diagrams. Only a few UML tools include extension
for real time modeling. The tool market around
MDA tools is still in flux and only about 10% of
them provide some support for MDA. Table 1
exemplifies a taxonomy of the UML CASE tools
(CASE, 2006).
The current techniques available in the commercial tools do not allow generating complete
243
Visio
MDA-based tools
244
rigOrOuS MOdeL-driven
deveLOPMent
Developing or reengineering a system in an MDA
perspective should be done through automated
245
246
FOrMaLizatiOn OF Mda-BaSed
PrOceSSeS
UML and OCL are too imprecise and ambiguous
when it comes to simulation, verification, validation, and forecasting of system properties and even
when it comes to generating models/implementations through transformations. Although OCL is a
textual language, OCL expressions rely on UML
class diagrams (i.e., the syntax context is determined graphically). OCL does also not have the
solid background of a classical formal language. In
the context of MDA, model transformations should
preserve correctness. To achieve this, the different
modeling and programming languages involved
in an MDD must be defined in a consistent and
precise way. Then, the combination of UML/OCL
specifications and formal languages offers the
best of both worlds to software developer. In this
direction, we define NEREUS to take advantage of
all the existing theoretical background on formal
methods, using different tools such as theorem
provers, model checkers, or rewrite engines in
different stages of MDD.
Favre (2006) proposes a rigorous framework
to model driven developments. The bases of
this approach are the metamodeling notation
NEREUS and, bridges between UML/OCL and
NEREUS and between NEREUS and algebraic
languages.
NEREUS can be viewed as an intermediate
notation open to many other formal specifications, such as algebraic, functional or logic ones.
NEREUS is suited for specifying MOF. Most of
the MOF concepts for metamodels (entity, associations, and packages) can be mapped to NEREUS
in a straightforward manner. This language is
relation-centric which means that it expresses
247
Metamodels
248
MOF
METAMODELS
NEREUS
Formal
Languages
Future trendS
Nowadays, there exists an increased demand of
reengineering of legacy systems towards new
technologies. Advanced MDA tools should reverse existing code to abstract models to facilitate
platform migration. It will probably take several
years before a full round trip engineering based
on standards occurs (many authors are skeptical
about this). The existing MDA-based tools do not
provide sophisticated transformation from PIM
to PSM and from PSM to code.
To solve problems basic research on formalisms and theories will have to be carried out
dealing with software evolution in MDA. If MDA
becomes a commonplace, adapting it to formal
development will become crucial. Formal and
semi-formal techniques can play complementary roles in software development processes.
This integration is beneficial for both graphical
and formal specification techniques. On the one
hand, semi-formal techniques have the ability to
visualize language constructs allowing a great
difference in the productivity of the specification
process, especially when the graphical view is
supported by means of good tools. On the other
hand, formal specifications allow us to produce a
precise and analyzable software specification before implementation and to define semi-automatic
forward engineering processes.
The integration between ontology (that are
essentially CIMs) and MDA will occupy a central
place in MDD (Djuric, Gasevic, & Devedzic,
2006). The use of formal specification will make
cOncLuSiOn
There is a great number of UML CASE tools in existence that facilitates code generation and limited
support for reverse engineering. Unfortunately, the
current techniques available in these tools provide
little automation for MDD. The formalization of
metamodels and metamodel-based model transformations can help to overcome these problems.
We propose to integrate knowledge developed by
the community of formal methods with MDA. A
rigorous framework for MDD was defined. It is
comprised of a metamodeling notation NEREUS,
a megamodel for defining MDA components
and the definition of metamodeling/model transformations based on MOF and NEREUS. We
define basic techniques for forward engineering
and reverse engineering.
We define systems of transformation rules
that allow translating MOF-metamodels to formal
specifications and implementations. A bridge
between NEREUS and algebraic languages was
defined by using CASL. Our approach focuses on
interoperability of formal languages.
We want to define foundations for MDA tools
that permit designers to directly manipulate the
visual models they have created. However, metadesigners need to understand metamodels and
metamodel transformations.
This research is still evolving and additional
issues will have to be tackled in order to fit advances in MDD.
249
acKnOWLedgMent
This work is partially supported by the Comisin
de Investigaciones Cientficas de la Provincia de
Buenos Aires (CIC).
reFerenceS
Ahrendt, W., Baar, T., Beckert, B., Giese, M.,
Hhnle, R., Menzel, W., Mostowski, W., &
Schmitt, P. (2002). The Key system: Integrating
object-oriented design and formal methods. In
R. Kutsche, & H. Weber (Eds.), Lecture notes
in computer science 2306 (pp. 327-330). Berlin:
Springer-Verlag.
Akehurst, D., & Kent, S. (2002). A relational
approach to defining transformations in a metamodel. In J. M. Jezequel, H. Hussmann, & S. Cook
(Eds.), Lecture notes in computer science 2460
(pp. 243-258). Berlin: Springer-Verlag.
Bidoit, M., & Mosses, P. (2004). CASL User manual--Introduction to using the common algebraic
specification language. Lecture Notes in Computer
Science 2900. Berlin: Springer-Verlag,
CASE. (2006). CASE TOOLS. Retrieved December 2006, from www.objectsbydesign.com
CWM. (2001). Common warehouse metamodel
(CWM) Specification, Version 1.1. Retrieved
December 2006, from www.omg.org/cgi-bin/
doc?ad/2001-02-01
Czarnecki, K., & Helsen, S. (2003). Classification
of model transformation approaches. In J. Bettin,
G. Van Emde, A. Agrawal, E. Willink, & J. Bezivin
(Eds.), Proceedings of OOPSLA03 Workshop on
Generative Techniques in the Context of ModelDriven Architecture. Retrieved December 2006,
from www.oopsla.org/oopsla2003
250
251
Thomas, D. (2005). Refactoring as meta programming? Journal of Object Technology, 4(1), 7-11.
Retrieved December 2006, from www.jot.fm/
issues/issue_2005_01/column1
UML. (2005). UML 2.0 Superstructure Specification. Document formal/2005-07-04. Retrieved
December 2006, from www.omg.org/cgi-bin/
doc?formal/05-07-04
KeY terMS
CASE Tool: Computer aided software engineering (CASE); a tool to aid in the analysis and
design of software systems.
Forward Engineering: The process of transforming a model into code through a mapping to
a specific implementation language.
MDA (Model Driven Architecture): A
framework based on UML and other industry
standards for visualizing, storing, and exchanging software design and models. It separates the
specification of functionality from the specification of the implementation of that functionality
on a specific technology platform.
This work was previously published in Encyclopedia of Information Science and Technology, Second Edition, edited by M.
Khosrow-Pour, pp. 1566-1573, copyright 2009 by Information Science Reference (an imprint of IGI Global).
252
253
Chapter 14
aBStract
The model-driven architecture (MDA) is an approach to model-centric software development. The
concepts of models, metamodels, and model transformations are at the core of MDA. Model-driven development (MDD) distinguishes different kinds of models: the computation-independent model (CIM),
the platform-independent model (PIM), and the platform-specific model (PSM). Model transformation
is the process of converting one model into another model of the same system, preserving some kind of
equivalence relation between them. One of the key concepts behind MDD is that models generated during software developments are represented using common metamodeling techniques. In this chapter, we
analyze an integration of MDA metamodeling techniques with knowledge developed by the community
of formal methods. We describe a rigorous framework that comprises the NEREUS metamodeling notation (open to many other formal languages), a system of transformation rules to bridge the gap between
UML/OCL and NEREUS, the definition of MDA-based reusable components, and model/metamodeling
transformations. In particular, we show how to integrate NEREUS with algebraic languages using the
Common Algebraic Specification Language (CASL). NEREUS focuses on interoperability of formal
languages in MDD.
intrOductiOn
The model-driven architecture (MDA) is an initiative of the Object Management Group (OMG,
www.omg.org), which is facing a paradigm shift
from object-oriented software development to
model-centric development. It is emerging as
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
and code, are regarded as models and are represented using common modeling languages.
MDA distinguishes different kinds of models:
the computation-independent model (CIM), the
platform-independent model (PIM), and the
platform-specific model (PSM). Unified Modeling Language (UML, www.uml.org) combined
with Object Constraint Language (OCL, www.
omg.org/cgi-bin/doc?ptc/2003-10-14) is the most
widely used way to specify PIMs and PSMs.
A model-driven development (MDD) is carried out as a sequence of model transformations.
Model transformation is the process of converting one model into another model of the same
system, preserving some kind of equivalence
relation between them. The high-level models
that are developed independently of a particular
platform are gradually transformed into models
and code for specific platforms.
One of the key concepts behind MDA is that all
artifacts generated during software developments
are represented using common metamodeling
techniques. Metamodels in the context of MDA
are expressed using meta object facility (MOF)
(www.omg.org/mof). The integration of UML
2.0 with the OMG MOF standards provides support for MDA tool interoperability (www.uml.
org). However, the existing MDA-based tools
do not provide sophisticated transformations
because many of the MDA standards are recent
or still in development (CASE, www.omg.org/
cgi-bin/doc?ad/2001-02-01). For instance, OMG
is working on the definition of a query, view,
transformations (QVT) metamodel, and to date
there is no way to define transformations between
MOF models (http://www.sce.carleton.ca/courses/
sysc-4805/w06/courseinfo/OMdocs/MOF-QVTptc-05-11-01.pdf). There is currently no precise
foundation for specifying model-to-model transformations.
MDDs can be improved by means of other
metamodeling techniques. In particular, in this
chapter, we analyze the integration of MDA
with knowledge developed by the formal method
254
BacKgrOund
the Model-driven architecture
MDA distinguishes different kinds of models:
the computation-independent model (CIM), the
platform-independent model (PIM), the platformspecific model (PSM), and code models. A CIM
describes a system from the computation-independent viewpoint that focuses on the environment of
and the requirements for the system. In general,
it is called a domain model and may be expressed
using business models. A PIM is a model that
255
Mda-Based tools
There are at least 100 UML CASE tools that differ
widely in functionality, usability, performance,
Figure 1. A simplified UML metamodel
256
and platforms. Currently, about 10% of them provide some support for MDA. Examples of these
tools include OptimalJ, ArcStyler, AndroMDA,
Ameos, and Codagen, among others. The tool
market around MDA is still in flux. References to
MDA-based tools can be found at www.objectsbydesign.com/tools. As an example, OptimalJ is
an MDA-based environment to generate J2EE
applications. OptimalJ distinguishes three kinds of
models: a domain model that correspond to a PIM
model, an application model that includes PSMs
linked to different platforms (Relational-PSM,
EJB-PSM and web-PSM), and an implementation
model. The transformation process is supported by
transformation and functional patterns. OptimalJ
allows the generation of PSMs from a PIM and a
partial code generation.
UML CASE tools provide limited facilities
for refactoring on source code through an explicit
selection made for the designer. However, it will
be worth thinking about refactoring at the design
257
FOrMaLizing MetaMOdeLS:
the nereuS Language
A combination of formal specifications and
metamodeling techniques can help us to address MDA. A formal specification clarifies the
intended meaning of metamodel/models, helps
to validate model transformations, and provides
reference for implementation. In this light, we
propose the intermediate notation NEREUS that
focuses on interoperability of formal languages.
It is suited for specifying metamodels based on
the concepts of entity, associations, and systems.
Most of the UML concepts for the metamodels
can be mapped to NEREUS in a straightforward
manner. NEREUS is relation-centric; that is, it
expresses different kinds of relations (dependency,
258
FUNCTIONS <functionList>
EFFECTIVE
TYPES <typesList>
FUNCTIONS <functionList>
AXIOMS <varList>
<axiomList>
END-CLASS
signatures in an incomplete way. NEREUS supports higher order operations (a function f is higher
order if functional sorts appear in a parameter
sort or the result sort of f ). In the context of OCL
Collection formalization, second-order operations
are required. In NEREUS, it is possible to specify
any of the three levels of visibility for operations:
public, protected, and private. NEREUS provides
the construction LET IN to limit the scope of
the declarations of auxiliary symbols by using
local definitions.
Several useful predefined types are offered
in NEREUS, for example, Collection, Set, Sequence, Bag, Boolean, String, Nat, and enumerated types. Figure 3 shows the predefined type
OCL-Collection.
Defining Associations
NEREUS provides a taxonomy of constructor
types that classifies binary associations according
to kind (aggregation, composition, association,
association class, qualified association), degree
259
Aggregation
Shared
...
Bidirectional
Non-Shared
Unidirectional
...
Qualified
...
Bidirectional
...
1..1
...
*..*
(unary, binary), navigability (unidirectional, bidirectional), and connectivity (one-to-one, one-tomany, many-to-many). Figure 4 partially depicts
the hierarchy of Binary Associations.
Generic relations can be used in the definition
of concrete relations by instantiation. New associations can be defined by means of the syntax
shown in Figure 5.
The IS paragraph expresses the instantiation
of <constructorTypeName> with classes, roles, visibility, and multiplicity. The CONSTRAINED-BY
clause allows the specification of static constraints
in first-order logic. Relations are defined in a class
by means of the ASSOCIATES clause.
Defining Packages
The package is the mechanism provided by
NEREUS for grouping classes and associations
260
: mult1; :
PACKAGE packageName
IMPORTS <importsList>
INHERITS <inheritsList>
<elements>
END-PACKAGE
END-CLASS
CLASS ThePackage
ASSOCIATES <<PackagePackage>>,
<<ClassPackage>>,
<< PackageAssociation >>
TYPE ThePackage
FUNCTIONS
name: ThePackage -> String
END-CLASS
CLASS TheAssociation
ASSOCIATES <<PackageAssociation>>,
<<AssociationAssociationEnd>>
TYPES TheAssociation
FUNCTIONS
name: TheAssociation -> String
END-CLASS
CLASS TheAssociationEnd
ASSOCIATES
<<AssociationAssociationEnd>>,
<<AssociationEndAssociationEnd>>,
<<SourceAssociationEnd>>,
<<TargetAssociationEnd>>,
END-CLASS
deFining reuSaBLe
cOMPOnentS: a MegaMOdeL
Developing reusable components requires a
high focus on software quality. The traditional
techniques for verification and validation are still
essential to achieve software quality. The formal
specifications are of particular importance for
supporting testing of applications, for reasoning
about correctness and robustness of models, for
checking the validity of a transformation and for
generating code automatically from abstract
models. MDA can take advantages of formal
CLASS TheInterface
ASSOCIATES <<ClassInterface>>,
END-CLASS
ASSOCIATION PackagePackage
IS Composition-2 [ThePackage: class1;
ThePackage: class2; thePackage : role1;
nestedPackages: role2; 0..1: mult1;
*: mult2; +: visibility1; +: visibility2]
END
ASSOCIATION ClassPackage
IS Bidirectional-2 [TheClass: class1;
ThePackage: class2; theClass: role1;
owner: role2; *: mult1; 1: mult2;
+: visibility1; +: visibility2]
END
ASSOCIATION ClassClass
IS Unidirectional-3 [TheClass: class1;
TheClass: class2; theClass: role1;
parents: role2; 1: mult1; *: mult2;
+: visibility1; +: visibility2]
END
ASSOCIATION ClassInterface
IS Bidirectional-4 [ TheClass: class1;
TheInterface: class2; theClass: role1;
implementedInt: role2; 0..*: mult1;
0..*: mult2; +: visibility1; +: visibility2]
END
ASSOCIATION SourceAssociationEnd
ASSOCIATION TargetAssociationEnd
ASSOCIATION PackageAssociation
ASSOCIATION
AssociationendAssociationend
END-PACKAGE
261
262
instance-of
bridge UML/OCL NEREUS
Metamodel Transformation
NEREUS
PIM
NEREUS
MODEL
Metamodel Transformation
UML/OCL
Model Transformation NEREUS
Model Transformation
UML/OCL
PIM
UML/OCL
METAMODEL
PIM
UML/OCL
MODEL
PICM
PSM
NEREUS
METAMODEL
PSM- J2EE
UML/OCL
METAMODEL
PSM-J2EE
NEREUS
MODEL
PSM-J2EE
UML/OCL
MODEL
NEREUS
METAMODEL
UML/OCL
METAMODEL
CODE
PSM
NEREUS
METAMODEL
PSM
UML/OCL
METAMODEL
PSM
NEREUS
MODEL
PSM
UML/OCL
MODEL
CODE
PSM-.NET
UML/OCL
METAMODEL
PSM. NET
NEREUS
MODEL
PSM-.NET
UML/OCL
MODEL
NEREUS
METAMODEL
UML/OCL
METAMODEL
PSM-.NET
NEREUS
METAMODEL
PSCM
NEREUS
METAMODEL
UML/OCL
METAMODEL
CODE
ICM
263
ASSOCIATION ___
IS __ [__: Class1; __:Class2; __: Role1;__:Role2;__:Mult1; __:Mult2; __:Visibility1; __:Visibility2]
CONSTRAINED BY __
END
Person
name: String
affiliation: String
address: String
Meeting
Participates
2..*
participants
numMeeting():Nat
numConfirmedMeeting(): Nat
264
*
meetings
title:String
start:Date
end:Date
isConfirmed:Bool
duration() :Time
checkDate():Bool
cancel()
numConfirmedParticipants():Nat
Figure 12. The package P&M: Translating interfaces and relations into NEREUS
PACKAGE P&M
CLASS Person
IMPORTS String, Nat
ASSOCIATES <<Participates>>
EFFECTIVE
TYPE Person
GENERATED-BY Create_Person
FUNCTIONS
createPerson: String x String x String -> Person
name: Person -> String
affiliation: Person -> String
address: Person -> String
set-name: Person x String -> Person
set-affiliation : Person x String -> Person
set-address: Person x String -> Person
AXIOMS p:Person; m: Meeting; s, s1, s2, s3:
String; pa: Participates
name(createPerson(s1,s2, s3)) = s1
affiliation (createPerson (s1, s2, s3) ) = s2
address (createPerson (s1, s2, s3)) = s3
set-name ( createPerson (s1, s2, s3), s) =
createPerson (s,s2,s3))
set-affiliation (createPerson( s1,s2, s3), s) =
createPerson (s1, s, s3))
END-CLASS
CLASS Meeting
IMPORTS String, Date, Boolean, Time
ASSOCIATES <<Participates>>
EFFECTIVE
TYPE Meeting
GENERATED-BY createMeeting
FUNCTIONS
createMeeting:
String x Date x Date x Boolean -> Meeting
tittle: Meeting -> String
start : Meeting -> Date
end : Meeting -> Date
isConfirmed : Meeting -> Boolean
set-tittle: Meeting x String -> Meeting
set-start : Meeting x Date -> Meeting
set-end: Meeting x Date -> Meeting
set-isConfirmed: Meeting x Boolean -> Boolean
AXIOMS s: String; d, d1,: Date; b:
Boolean;
title( createMeeting (s, d, d1, b) ) = s
start ( createMeeting (s, d, d1, b)) = d
end ( createMeeting (s, d, d1, b)) = d1
isConfirmed ( createMeeting (s, d, d1, b)) = b
...
END-CLASS
ASSOCIATION Participates
IS Bidirectional-Set [Person: Class1; Meeting:
Class2; participants: Role1; meetings: Role2; *:
Mult1; * : Mult2; + : Visibility1; +: Visibility2]
END
END_PACKAGE
NEREUS
v (variable)
v. operation (v)
v->operation (v)
v.attribute
context A
object.rolename
operation (v, v)
operation (v, v)
attribute (v )
get_ rolename (A, object)
e.op
265
Figure 14. The package P&M: Transforming OCL contracts into NEREUS
context Meeting:: checkDate():Bool
OCL
post: result = self.participants->collect(meetings) ->forAll(m | m<> self and
m.isConfirmed implies (after(self.end,m.start) or after(m.end,self.start)))
context Meeting::isConfirmed ()
post: result= self.checkdate() and self.numConfirmedParticipants >= 2
context Person:: numMeeting ( ): Nat
post: result = self.meetings -> size
context Person :: numConfirmedMeeting ( ) : Nat
post: result= self.meetings -> select (isConfirmed) -> size
Rule 1
T Op (<parameterList>) : ReturnType
post: expr
Rule 2
T->
forAll op (v:Type |bool-exprwith-v)
op ::= exists |select | reject
Rule 3
T -> collect ( v :type |v.property)
AXIOMS t : T, ...
TranslateNEREUS (exp)
CLASS Person...
AXIOMS p:Person; s,s: String; Pa: Participates
NEREUS
numConfirmedMeetings (p) =
size(selectm (getMeetings(Pa,p), [isConfirmed (m)] )
Rule 1, 2
numMeetings (p) = size (getMeetings (Pa, p))
Reglas 1
END-CLASS
CLASS Meeting
AXIOMS m,m1:Meeting; s,s:String; d,d,d1,d1:Date; b,b:Boolean;
Pa:Participates
isConfirmed (cancel(m)) = False
isConfirmed (m)=checkDate(m) and NumConfirmedParticipants (m) >= 2 Rule 1
checkDate(m) =
Rules 1, 2, 3
forAllme (collectp (getParticipants(Pa,m), [getMeetings (Pa, p)]), [consistent (m,me)] )
consistent(m,m1)= not (isConfirmed(m1)) or (end(m) < start(m1) or end(m1) < start(m))
NumConfirmedParticipants (m) = size (getParticipants(Pa,m))
END-CLASS
A ddPerson (p:Person)
is translated into:
266
NEREUS
CASL
267
CLASS A
INHERITS B, C
CASL
268
translating associations
NEREUS and UML follow similar structuring
mechanisms of data abstraction and data encapsulation. The algebraic languages do not follow
these structuring mechanisms in an UML style.
In UML, an association can be viewed as a local
part of an object. This interpretation cannot be
mapped to classical algebraic specifications, which
do not admit cyclic import relations.
We propose an algebraic specification that
considers associations belonging to the environment in which an actual instance of the class is
embedded. Let Assoc be a bi-directional association between two classes called A and B;
the following steps can be distinguished in the
translation process. We exemplify these steps with
the transformation of P&M (see Figure 11).
269
operations/attributes
person
name
meeting
Step 1:
Regroup the operations of classes A and B
distinguishing operations local to A, local
to B and, local to A and B and Assoc (Figure 20).
Step 2:
Construct the specifications A and B from
A and B where A and B include local operations to A and B respectively (Figure 21).
Step 3:
Construct specifications Collection[A] and
Collection[B] by instantiating reusable
schemes (Figure 22).
Step 4:
Construct a specification Assoc (with A and
B) by instantiating reusable schemes in the
component Association (Figure 23).
Step 5:
Construct the specification AssocA+B by
extending Assoc with A, B and the operations local to A, B and Assoc (Figure 24).
Figure 25 depicts the relationships among the
specifications built in the different steps.
270
nummeetings
great difference in the productivity of the specification process, especially when the graphical
view is supported by good tools. On the other
hand, formal specifications allow us to produce
a precise and analyzable software specification
and automate model-to-model transformations;
however, they require familiarity with formal
notations that most designers and implementers
do not currently have, and the learning curve
for the application of these techniques requires
considerable time.
UML and OCL are too imprecise and ambiguous when it comes to simulation, verification,
validation, and forecasting of system properties
and even when it comes to generating models/
implementations through transformations. Although OCL is a textual language, OCL expressions rely on UML class diagrams, that is, the
syntax context is determined graphically. OCL
does also not have the solid background of a classical formal language. In the context of MDA,
model transformations should preserve correctness. To achieve this, the different modeling and
programming languages involved in a MDD must
be defined in a consistent and precise way. Then,
the combination of UML/OCL specifications and
formal languages offers the best of both worlds
to the software developer. In this direction, we
define NEREUS to take advantage of all the existing theoretical background on formal methods,
using different tools such as theorem provers,
model checkers, or rewrite engines in different
stages of MDD.
In contrast to other works, our approach is the
only one focusing on the interoperability of formal
languages in model-driven software development.
end
end
There are UML formalizations based on different languages that do not use an intermediate
language. However, this extra step provides some
advantages. NEREUS would eliminate the need
to define formalizations and specific transformations for each different formal language. The
metamodel specifications and transformations can
be reused at many levels in MDA. Languages that
are defined in terms of NEREUS metamodels can
be related to each other because they are defined
in the same way through a textual syntax.
271
272
numMeetings
numConfirmedMeetings
isConfirmed
checkDate
cancel
PERSON&MEETING
getMeetings
PARTICIPATES
PARTICIPATES
SETPERSON
SET MEETING
SETMEETING
SET PERSON
PERSON
PERSON
getParticipates
name
set-name
Future trendS
Currently, OMG is promoting a transition from
code-oriented to MDA-based software development techniques. The existing MDA-based tools
do not provide sophisticated transformation from
PIM to PSM and from PSM to code. To date, they
might be able to support forward engineering
and partial round-trip engineering between PIM
MEETING
MEETING
title
start
end
duration
273
cOncLuSiOn
In this chapter, we describe a uniform framework
for model-driven development that integrates
UML/OCL specifications with formal languages.
It is comprised of a megamodel for defining
MDA components, a metamodeling notation
NEREUS, and the definition of metamodeling/
model transformations using UML/OCL and
NEREUS.
A megamodel integrates PIMs, PSMs and
code models with their respective metamodels. We
formalize UML-based metamodels in NEREUS,
which is an intermediate notation particularly
suited for metamodeling. We define a system of
transformation rules to bridge the gap between
UML/OCL models and NEREUS. We propose to
specify metamodel transformations independently
of any technology. We investigate the way to define
them using UML/OCL and NEREUS.
We want to define foundations for MDA tools
that permit designers to directly manipulate the
UML/OCL models they have created. However,
meta-designers need to understand metamodels
and metamodel transformations.
We are validating the megamodel through
forward engineering, reverse engineering, model
refactoring, and pattern applications.
We foresee the integration of our results in the
existing UML CASE tools, experimenting with
different platforms such as .NET and J2EE.
274
reFerenceS
Abmann, U. (Ed.). (2004). Proceedings of
Model-Driven Architecture: Foundations and
applications. Switzerland: Linkoping University.
Retrieved February 28, 2006, from http://www.
ida.liv.se/henla/mdafa2004
Ahrendt, W., Baar, T., Beckert, B., Bubel, R.,
Giese, M., Hhnle, R., et al. (2005). The key tool.
Software and Systems Modeling, 4, 32-54.
Akehurst, D., & Kent, S. (2002). A relational
approach to defining transformations in a metamodel. In J. M. Jezequel, H. Hussmann, & S. Cook
(Eds.), Lecture Notes in Computer Science 2460
(pp. 243-258). Berlin: Springer-Verlag.
Atkinson, C., & Kuhne, T. (2002). The role of
metamodeling in MDA. In J. Bezivin & R. France
(Eds.). Proceedings of UML 2002 Workshop in
Software Model Engineering (WiSME 2002),
Dresden, Germany. Retrieved February 28, 2006,
from http://www.metamodel.com/wisme-2002
Bzivin, J., Farcet, N., Jzquel, J., Langlois, B.,
& Pollet, D. (2003). Reflective model driven engineering. In P. Stevens, J. Whittle, & G. Booch
(Eds.), Lecture Notes in Computer Science 2863
(pp.175-189). Berlin: Springer-Verlag.
Bzivin, J., Jouault, F., & Valduriez, P. (2004).
On the need for megamodels. In J. Bettin, G. van
Emde Boas, A. Agrawal, M. Volter, & J. Bezivin
(Eds.), Proceedings of Best Practices for ModelDriven Software Development (MDSD 2004),
OOSPLA 2004 Workshop, Vancouver, Canada.
Retrieved February 28, 2006, from http://www.
softmetaware.com/oospla2004
Bidoit, M., & Mosses, P. (2004). CASL user
manual- Introduction to using the Common
Algebraic Specification Language. In Lecture
Notes in Computer Science 2900 (p. 240). Berlin:
Springer Verlag.
Caplat, G., & Sourrouille, J. (2002). Model mapping in MDA. In J. Bezivin & R. France (Eds.),
Proceedings of UML 2002 Workshop in Software
Model Engineering (WiSME 2002). Retrieved
February 28, 2006, from http://www.metamodel.
com/wisme-2002
Favre, L., Martinez, L. & Pereira, C. (2005). Forward engineering of UML static models. In M.
Khosrow-Pour (Ed.), Encyclopedia of information
science and technology (pp. 1212-1217). Hershey,
PA: Idea Group Reference.
Gogolla, M., Bohling, J., & Richters, M. (2005).
Validating UML and OCL models in USE by
automatic snapshot generation. Journal on Software and System Modeling. Retrieved from http://
db.informatik.uni-bremen.de/publications
Gogolla, M., Lindow, A., Richters, M., & Ziemann, P. (2002). Metamodel transformation of
data models. In J. Bzivin & R. France (Eds.),
Proceedings of UML2002 Workshop in Software
Model Engineering (WiSME 2002). Retrieved
February 28, 2006, from http://www.metamodel.
com/wisme-2002
Gogolla, M., Sammut, P., & Whittle, J. (Eds.).
(2004). Proceedings of WISME 2004, 3rd Workshop on Software Model Engineering. Retrieved
February 28, 2006, from http://www.metamodel.
com/wisme-2004
Haussmann, J. (2003). Relations-relating metamodels. In A. Evans, P. Sammut, & J. Williams
(Eds.), Proceedings of Metamodeling for MDA.
First International Workshop. Retrieved February
28, 2006, from http://www.cs.uni-paderborn.de/
cs/ag-engels/Papers/2004/MM4MD Ahausmann.
pdf
275
endnOte
1
This work was previously published in Advanced Topics in Database Research, Volume 5, edited byK. Siau, pp. 1-27, copyright
2006 by IGI Publishing (an imprint of IGI Global).
276
Section 6
Appendices
278
Appendix A:
Abstract syntax: It consists of one or more UML class diagrams that show the metaclasses defining constructs and relationships. The shaded metaclasses belong to the UML metamodel.
Metaclasses description: Natural language is used to describe metaclasses, generalizations and
associations. Constraints are specified in OCL. Metaclasses are listed in alphabetic order.
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
Appendix A
Generalization
Attributes
No additional attributes
Associations
class: EiffelClass [0..1] It refers to the class of which this association-end is part
Attribute
Description
It represents the attributes declared in a class Eiffel.
Generalization
279
Appendix A
Attributes
isFrozen: Boolean [1] It specifies whether an attribute is frozen, i.e., constant. In this case, it must
have an initial value. It redefines RedefinableElement::isLeaf.
Associations
class: EiffelClass [1] It refers to the class declaring this attribute. It redefines Property::class.
Constraints
[1] An attribute is a property which is part of a class and but not member of any association. self.class
-> size () = 1 and self.association-> isEmpty () and self.opposite-> isEmpty ()
EiffelClass
Description
An Eiffel class describes a set of objects which share the same specifications of features, restrictions
and semantics.
280
Appendix A
Generalizations
Attributes
isDeferred Boolean [1] It specifies whether a class is deferred, i.e., one or more features, that are
specified but not implemented, are included in the class. It redefines Classifier::isAbstract.
isExpanded: Boolean [1] It specifies whether the class is flattened, i.e., its instances are objects
but no references to objects.
Associations
associationEnd: AssociationEnd [*] It refers to the own association-ends of the class Eiffel. It is a
subset of Class::ownedAttribute.
attribute: Attribute [*] It refers to the own variables of the Eiffel class. It is a subset of
Class::ownedAttribute.
generalization: Generalization [*] It specifies generalizations.
invariant: Constraint [*] It refers to class invariants. It redefines NameSpace::ownedRule.
/parameters: TemplateParameter [*] It refers to the set of parameters of the class. It is derived.
/parents: EiffelClass [*] It refers to supeclasses of an Eiffel class. It redefines Class::superclass.
It is derived.
routine: Routine [*] It refers the own operations of the class. It redefines Class::ownedOperation.
281
Appendix A
Constraints
[1] A class, with at least a deferred routine, must be declared deferred. self.ownedRoutine -> exists (r
| r.isDeferred) implies self. isDeferred
[2] Private routines of a class can not be declared abstract. self.ownedRoutine -> forAll (r | r.visibility
= #private implies not r.isAbstract)
[3] Frozen routines of a class can not be declared deferred. self.ownedRoutine -> forAll (r | r.isFrozen
implies not r.isDeferred)
[4] An Eiffel class does not have nested classes. self.nestedClassifier -> isEmpty ()
[5] parents is derived from generalization. parents = self.generalization.parent
[6] parameters is derived from the parameters of the signature template that can be redefined. parameters = ownedSignature.parameter
Function
Description
It declares a function that can be called passing a fixed number of arguments.
Generalizations
Routine
Attributes
No additional attributes.
Associations
returnType: Type [1] It refers to the return type of the function. It redefines Operation::type.
Constraints
[1] A function must have a return type and therefore, its set of arguments includes one argument whose
type is return. self.ownedParameter -> select (p | p.direction = #return) -> size = 1
Implementation
Description
It specifies a procedure that realizes a routine.
Generalization
282
Appendix A
Attributes
Associations
Constraints
[1] A routine can not call a constructor. self.invokedRoutine -> select (r | r.oclIsTypeOf (Procedure))
-> forAll (p | not p.oclAsType (Procedure).isConstructor)
Procedure
Description
It declares a procedure that can be invoked by passing a fixed number of arguments.
Generalizations
Routine
Attributes
Associations
No additional associations.
Constraints
[1] A procedure does not have a return type. self.ownedParameter -> select(p | p.direction = #return)
-> isEmpty ()
[2] The constructor of a class can not be abstract. self.isConstructor implies not self.isDeferred
Routine
Description
It specifies the characteristics of an Eiffel routine.
283
Appendix A
Generalizations
Attributes
isDeferred: Boolean [1] It specifies whether a routine is deferred, i.e., without implementation.
isFrozen: Boolean [1] It specifies whether a routine is final, i.e., it can not be redefined in a descendent class. It redefines RedefinableElement::isLeaf.
Associations
Constraints
[1] A deferred routine does not have implementations. self.isDeferred implies self.body -> isEmpty
()
284
Appendix A
AssociationEnd
Description
It specifies the characteristics of an Eiffel routine.
Generalization
285
Appendix A
Attributes
No additional attributes.
Associations
class: JavaClass [0..1] It refers to the class of which this association-end is part. It redefines
Property::class.
Constraints
[1] An association-end is a property that is member of an association. self.association -> size () = 1
Constructor
Description
It designs an operation that is used to create class instances. They can not be explicitly invoked by means
of expressions of method call. Constructors do not have return type and have the same name of the class
containing the declaration. Constructor declarations can not be inherited.
Generalization
286
JavaOperation
Appendix A
Attributes
No additional attributes.
Associations
No additional associations.
287
Appendix A
Constraints
[1] Constructors do not have return type. self.type -> isEmpty ()
[2] The constructor name is equal to the name of the class containing the declaration. self.name = self.
class.name
Field
Description
It specifies the attributes declared in a class or interface.
Generalization
Attributes
isFinal: Boolean [1] It specifies whether an attribute is final, i.e., constant. In this case, it must
have an initial value. It redefines RedefinableElement::isLeaf.
isTransient: Boolean [1] It specifies whether an attribute is part of the persistent state of the
object.
isVolatile: Boolean [1] It specifies whether an attribute is volatile, i.e., it is accessed
asynchronously.
Associations
class: JavaClass [0..1] It refers to the class declaring this attribute. It redefines Property::class.
Constraints
[1] An attribute is a property that is part of a class and is not member of associations. self.class -> size
() = 1 and self.association -> isEmpty () and self.opposite -> isEmpty ()
Implementation
Description
It specifies the procedure of the operation.
Generalization
288
Appendix A
Attributes
Associations
invokedMethod: Method [*] It refers to the methods invoked in the body of an operation.
referencedField: Field [*] It refers to the variables referred in the body of an operation.
signature: JavaOperation [1] It specifies the operation that implements.
Constraints
No additional constraints.
JavaClass
Description
A Java class describes a set of objects sharing the same specifications of features, constraints and semantics.
Generalizations
Attributes
isFinal: Boolean It specifies whether the class can have subclasses. It redefines
RedefinableElement::isLeaf.
/isGeneric: Boolean It specifies whether the class is generic. It is a derived attribute.
isStatic: Boolean It specifies whether the class is static.
Associations
associationEnd: AssociationEnd [*] It refers to the own association-end of the Java class. It is
subset of Class::ownedAttribute
field: Field [*] It refers to own variables of the Java class. It is a subset of Class::ownedAttribute
/implement: JavaInterface [*] It refers to the Java interfaces implemented by this class. It is
derived.
javaOperation: JavaOperation [*] It refers the own operations of the class. It redefines
Class::ownedOperation
javaPackage: JavaPackage [0..1] It refers to the package in which it is declared. It redefines
Type::package.
nestedClass: JavaClass [*] It refers to the Java classes declared within of the body of a JavaClass
(nested classes).
289
Appendix A
nestedInterface: JavaInterface [*] It refers to the Java interfaces declared within the body of a
JavaClass (nested interfaces). It is a subset of Class::nestedClassifier.
/parameters: TemplateParameter [*] It refers the set of parameters of the class. It is derived.
/superClass: JavaClass [1] It refers to the superclass of a Java class. It redefines Class::superclass.
It is derived.
Constraints
[1] Nested classifiers of a class or interface can only be of the type JavaClass or JavaInterface. self.
nestedClassifier -> forAll (c | c.oclIsTypeOf (JavaClass) or c.oclIsTypeOf (JavaInterface))
[2] The implemented interfaces are those referred through the interface realization. implement = self.
interfaceRealization.contract
[3] A class having at least an abstract method must be declared abstract. self.javaOperation -> select
(op | op.oclIsTypeOf (Method)) -> exists (m | m.oclAsType(Method).isAbstract) implies self.
isAbstract
[4] A class that is declared abstract does not have a constructor explicitly defined. self.isAbstract
implies self.javaOperation -> select (op | op.oclIsTypeOf (Constructor)) -> isEmpty ()
[5] A class that is declared final does not have subclasses, i.e., it is not superclass of any class. self.
isFinal implies self.javaPackage.ownedMember -> select (m | m.oclIsTypeOf (JavaClass)) -> forAll
(c | c.oclAsType (JavaClass).superClass <> self)
[6] The access level protected, private and static can be only applied to nested classes, i.e., declared
within the declaration of another class. (self.visibility = #protected or self.visibility = #private or
self.isStatic) implies self.javaPackage.ownedMember -> select (m | m.oclIsTypeOf (JavaClass))
-> exists (c | c.oclAsType (JavaClass).nestedClass -> includes (self))
[7] Private methods of a class can not be declared abstract. self.javaOperation -> select (op |
op.oclIsTypeOf (Method)) -> forAll (m | m.visibility = #private implies not m.oclAsType (Method).
isAbstract)
[8] Static methods of a class can not be declared abstract. self.javaOperation -> select (op | op.oclIsTypeOf
(Method)) -> forAll (m | m.isStatic implies not m.oclAsType (Method).isAbstract)
[9] A method that isFinal can not be declared abstract. self.javaOperation -> select (op | op.oclIsTypeOf
(Method)) -> forAll (m | m.oclAsType(Method).isFinal implies not m.oclAsType (Method).
isAbstract)
[10] A class is generic if has a template signature. isGeneric = (self.ownedTemplateSignature -> size
() =1)
[11] parameters is derived starting from of the parameters of the template signature. /parameters = self.
ownedTemplateSignature.parameter
JavaInterface
Description
It describes the characteristics of the interfaces in the Java platform.
290
Appendix A
Generalizations
Attributes
No additional attributes.
Associations
Constraints
[1] The Java interfaces are implicitly abstract. self.isAbstract
[2] The own member of an interface are implicitly public. self.ownerMember -> forAll (m | m.visibility
= #public)
[3] Nested classifiers of an interface can only be of the type JavaClass or JavaInterface. self.nestedClassifier -> forAll (c | c.oclIsTypeOf (JavaClass) or c.oclIsTypeOf (JavaInterface))
[4] An interface can only be declared private or protected if it is directly nested in the class declaration. (self.visibility = #protected or self.visibility = #private) implies self.package.ownedMember
-> select (m | m.oclIsTypeOf (JavaClass)) -> exists (c | c.oclAsType (JavaClass).nestedInterface
-> includes (self))
[5] An interface can only be declared static if it is directly nested in the class or interface declaration. self.
isStatic implies self.package.ownedMember -> select (m | m.oclIsTypeOf (JavaClass)) -> exists
(c | c.oclAsType (JavaClass).nestedInterface -> includes (self)) or self.package.ownedMember ->
select (m | m.oclIsTypeOf (JavaInterface)) -> exists (i | i.oclAsType (JavaInterface).nestedInterface
-> includes (self))
[6] Methods that are declared in an interface are abstract and hence do not have implementations. self.
method ->forAll (m| m.isAbstract and m.body -> isEmpty ())
[7] Methods of an interface can not be declared static. self.method -> forAll (m| not m.isStatic)
291
Appendix A
[8] Methods of an interface can not be synchronized. self.method -> forAll (m| not
m.isSynchronized)
[9] Fields of an interface are implicitly public, static or final. self.field ->forAll (f | f.visibility = #public
and f.isStatic and f.isFinal)
[10] superInterface is derived of the generalization. /superInterface = self.generalization.general
[11] Parameters are derived from the parameters of the template signature. /parameters = self.ownedTemplateSignature.parameter
JavaOperation
Description
It describes the characteristics of the interfaces in the Java platform.
Generalization
Attributes
No additional attributes.
Associations
class: JavaClass [0..1] It refers to the class declaring the operation. It redefines Operation::class.
body: Implementation [0..1] It refers to the implementation of the operation.
javaException: JavaClass [*] It refers to the types that represent the exceptions that can appear
during an invocation of this operation.
Constraints
[1] An abstract operation does not have implementation. self.isAbstract implies self.body -> isEmpty
()
JavaPackage
Description
It is used for grouping elements. Its members can be classes, interfaces or sub-packages.
Generalization
Attributes
No additional attributes.
292
Appendix A
Associations
javaClass: JavaClass [*] It refers to classes that are members of this package. It is a subset of
Package::ownedType.
javaInterface: JavaInterface [*] It refers to all interfaces that are members of this package. It is a
subset of Package::ownedType.
/subpackage: Package [*] It refers to the packages that are members of this package. It is
derived.
Constraints
No additional constraints.
Method
Description
It declares an operation that can be invoked by passing a fixed number of the arguments.
Generalizations
JavaOperation
Attributes
isAbstract: Boolean [1] It specifies whether a method is abstract, i.e., it does not have
implementation.
isFinal: Bolean It specifies whether a method is final. In this case, it can not be overwritten in a
derived class. It redefines RedefinableElement::isLeaf.
isSyncronized: Boolean [1] It specifies whether a method is synchronized. It is true if acquires a
lock before execution.
Associations
interface: JavaInterface [0..1] It declares the interface that declares this method. It redefines
Operation::interface.
Constraints
No additional restrictions.
293
Appendix A
Attributes
isConstant: Boolean [1] It specifies whether an attribute is constant. In this case it must have a
compulsory initial value.
Associations
class: EiffelClass [1] It refers to the class that declares this attribute. It redefines Property::class.
type: EiffelClass [1] It refers to the type of this attribute. It redefines TypedElement::type.
Constraints
[1] An attribute is a property that is part of a class and is not member of associations. self.class -> size
() = 1 and self.association -> isEmpty () and self.opposite -> isEmpty ()
Assertion
Description
It describes assertions, according to the specification of the Eiffel language.
Generalization
Attributes
294
Appendix A
Associations
class [0..1]: EiffelClass It refers to the class that is the context in which this restriction is evaluated. It is a subset of Constraint::context.
routine [0..1]: Routine It refers to the routine that is the context in which this restriction is evaluated. It is a subset of Constraint::context.
Constraints
No additional restrictions.
295
Appendix A
Argument
Description
It describes the arguments of a routine.
296
Appendix A
297
Appendix A
Generalization
Attributes
No additional attributes.
Associations
type: EiffelClass [1] It refers to the type of this argument. It redefines TypedElement::type.
Constraints
No additional constraints.
Cluster
Description
It is used to group and organize classes in Eiffel.
Generalization
Attributes
No additional attributes.
Associations
ownedClass: EiffelClass [*] It refers to Eiffel classes that are members of this cluster. It redefines
Package::ownedType.
Constraints
No additional constraints.
Compound
Description
It describes a set of instructions, according to the specification of the Eiffel language.
Generalization
298
Appendix A
Attributes
No additional attributes.
Associations
instruction: Instruction [*] It specifies the set of instructions that forms the compound. It is
ordered.
Constraints
No additional constraints.
EntityDeclaration
Description
It describes a local entity of a routine, according to the specification of the Eiffel language.
Generalization
Attributes
No additional attributes.
Associations
type [1]: EiffelClass It specifies the type of the entity. It redefines TypedElement::type.
Constraints
No additional constraints.
EiffelClass
Description
An Eiffel class describes a set of objects sharing the same feature specifications, restrictions and semantics.
Generalizations
Attributes
isDeferred: Boolean [1] It specifies whether a class is deferred, i.e., it includes one or more features that are specified but no implemented. It redefines Classifier::isAbstract.
299
Appendix A
isExpanded: Boolean [1] It specifies whether the class is flattened, i.e. its instances are objects but
no references to objects.
isObsolete: Boolean [1] It specifies whether the class is obsolete.
Associations
attribute: Attribute [*] It refers to the own attributes of the Eiffel class. It redefines
Class::ownedAttribute.
eiffelFeatures: EiffelFeature [*] It refers the features of which this class is client.
generalization: Generalization [*] It specifies the generalization for this class.
invariant: Assertion [*] It refers to invariants of the class. It redefines NameSpace::ownedRule.
ownedRoutine: Routine [*] It refers to the own routines of the class. It redefines
Class::ownedOperation.
/parameters: EiffelParameter [*] It refers to the set of parameters of the class. It is derived.
/parent: EiffelClass [*] It refers to the parent class of an Eiffel class. It redefines Class::superClass.
It is derived.
Constraints
[1] A class having a deferred routine must be declared deferred. self.ownedRoutine -> exists (r |
r.isDeferred) implies self. isDeferred
[2] Secret routines can not be declared deferred. self.ownedRoutine -> forAll (r | r.availability = #secret
implies not r.isDeferred)
[3] Frozen routines of a class can not be declared deferred. self.ownedRoutine -> forAll (r | r.isFrozen
implies not r.isDeferred)
[4] An Eiffel class has not nested classes. self.nestedClassifier -> isEmpty ()
[5] ancestors is derived of the generalization. ancestors = self.generalization.parent
[6] parameters is derived from the parameters of the template signature that can be redefined. parameters = ownedSignature.parameter
[7] Parameters of a class are of the type Eiffel class. self.parameters.parameteredElement -> forAll (p
| p.oclIsTypeOf (EiffelClass))
[8] A deferred class has not creation procedure. self.class.isDeferred implies self.ownedRoutine ->
select (p | p.oclIsTypOf (Procedure) and p.isCreator) -> isEmpty ()
[9] A flattened class has only a creation procedure without arguments. self.class.isExpanded implies self.
ownedRoutine -> select (p | p.oclIsTypeOf (Procedure) and p.isCreator) -> size () = 1 and self.
ownedRoutine -> select (p | p.isCreator and p.argument -> isEmpty ()) -> size () = 1
[10] A flattened class does not have parameters. self.class.isExpanded implies self.parameter -> isEmpty
()
EiffelParameter
Description
It specifies the parameters of a class, according to the specification of the Eiffel language.
300
Appendix A
Generalizations
Attributes
No additional attributes.
Associations
No additional associations.
Constraints
[1] The type of the parameters of a class is EiffelClass. self.parameteredElement -> forAll (p |
p.oclIsTypeOf (EiffelClass))
EiffelFeature
Description
It declares a feature, according to the specification of the Eiffel language.
Generalizations
NamedElement
Attributes
Associations
clients: EiffelClass[*] It refers to the classes for which this feature is available.
Constraints
[1] If the feature is selectively available, then it must be associated to a list of clients, else the list of
clients is empty. if self.availability = #selectively_available then self.client -> size () > 0 else self.
client -> isEmpty() endif
FeatureAvailability
Description
FeatureAvailability is an enumeration of the following values:
301
Appendix A
available
secret
selectively available
which determine whether a feature is available in all classes, some classes or no classes.
Generalizations
None
Function
Description
It declares a function, according the specification of the Eiffel language.
Generalizations
Routine
Attributes
No additional attributes.
Associations
/type: EiffelClass[1] It refers to the return type of the function. It redefines TypedElement::type.
Constraints
No additional restrictions.
Instruction
Description
It describes an instruction, according to the specification of the Eiffel language.
Generalizations
Attributes
No additional attributes.
Associations
302
routineBody: RoutineBody It refers to the body of the routine of which this instruction forms a
part.
Appendix A
routine: Routine It refers to the routine that declares the clause rescue of which this instruction is
a part.
Constraints
No additional constraints.
Routinebody
Description
It specifies the body of the routine, according to the specification of the Eiffel language.
Generalization
Attributes
is Deferred: Boolean It specifies whether the body is deferred, i.e., it is not implemented.
Associations
signature: Routine [1] It refers to the routine to which corresponds this implementation.
instruction: Instruction [0..1] It refers to the instruction that composes the body of the routine.
Constraints
[1] If the body if the routine is deferred, then the routine declaring it is also deferred. self.isDeferred
implies self.signature.isDeferred
Procedure
Description
It declares a procedure, according the specification of the Eiffel language.
Generalizations
Routine
Attributes
Associations
No additional associations.
303
Appendix A
Constraints
[1] A procedure does not have a return type. self.ownedParameter -> select (p | p.direction = #return)
-> isEmpty ()
[2] If a procedure is a creation procedure then it can not be deferred. self.isCreator implies not self.
isDeferred
Routine
Description
It specifies the features of a routine Eiffel.
Generalizations
Attributes
isDeferred: Boolean [1] It specifies whether a routine is deferred, i.e., it does not have
implementation.
isFrozen: Boolean [1] It specifies whether a routine is final, i.e., it can not be redefined in a descendent class. It redefines RedefinableElement::isLeaf
isOnce: Boolean [1] It specifies whether the routine is executed only a time.
isObsolete: Boolean [1] It specifies whether the routine is obsolete.
Associations
argument: Argument [*] It refers to the formal arguments of the routine. It redefines
Operation::OwnedParameter.
body: RoutineBody [1] It refers to the implementation of the routine.
class: EiffelClass [1] It refers to a class that declares this routine. It redefines Operation::class.
ensure: Assertion [*] It specifies the postconditions of the routine. It redefines
Operation::postcondition.
localEntity: EntityDeclaration [*] It specifies the local entities of the routine.
require: Assertion [*] It specifies the preconditions of the routine. It redefines
Operation::precondition.
rescue: Instruction [0..1] It specifies that the answer to an exception occurs during the execution
of the routine.
Constraints
[1] If a routine is deferred then it does not have implementation. self.isDeferred implies self.body>isEmpty ()
[2] If a routine is frozen, then it can not be deferred. self.isFrozen implies self.isDeferred
304
Appendix A
Simple Instruction
Description
It describes a simple instruction, according to the specification of the Eiffel language.
Generalizations
Attributes
No additional attributes.
Associations
No additional associations.
Constraint
No additional restrictions.
Attributes
No additional attributes
Associations
blockStatement: blockStatement [0..1] It refers to the statements of which this block is part.
implementation: Implementation [1] It refers to the implementation of which this block is part.
305
Appendix A
306
Appendix A
Constraints
No additional constraints.
Constructor
Description
It is a constructor, according to the definition in the Java language.
Generalization
JavaOperation
Attributes
No additional attributes.
Associations
No additional associations.
Constraints
[1] A constructor does not have a return type. self.returnType -> isEmpty ()
[2] The constructor name is equal to the class name including the declaration. self.name = self.class.
name
Field
Description
It represents an attribute, as is defined in the Java language.
307
Appendix A
Generalization
Attributes
308
isFinal: Boolean [1] It specifies whether an attribute is final, i.e., constant. If an attribute is final,
then it must have an initial value.
isTransient: Boolean [1] It specifies whether an attribute is part of the persistent state of the
object.
isVolatile: Boolean [1] It specifies whether an attribute is volatile, i.e., it is accessed nonsynchronically.
Appendix A
Associations
class: JavaClass [0..1] It refers to the class declaring this attribute. It redefines Property::class.
javaType: JavaType [1] It refers to the attribute type. It redefines TypedElement::type.
Constraints
[1] An attribute is a property that is a part of a class and is not member of associations. self.class ->
size () = 1 and self.association -> isEmpty () and self.opposite -> isEmpty ()
Implementation
Description
It specifies a procedure that obtains the result of the operation.
Generalization
Attributes
No additional attributes.
309
Appendix A
Associations
Constraints
No additional constraints.
JavaClass
Description
A Java class as is defined in the Java language.
Generalizations
Attributes
310
redefines
Appendix A
Associations
field: Field [*] It refers to the own variables of the Java class. It redefines Class::ownedAttribute.
/implement: It refers to the Java interfaces that are implemented by this class. It is derived.
javaOperation: JavaOperation [*] It refers the own operations of the class. It redefines
Class::ownedOperation.
javaPackage: JavaPackage [0..1] It refers to the package in which is declared. It redefines
Type::package.
nestedClass: JavaClass [*] It refers to the Java classes that are declared within the body of a Java
class (nested classes). It is a subset of Class::nestedClassifier.
nestedInterface: JavaInterface [*] It refers to the Java interfaces that are declared within the body
of a JavaClass (nested interfaces). It is a subset of Class::nestedClassifier.
/parameters: JavaParametes [*] It refers to the set of parameters of a class. It is derived.
/superClass: JavaClass [1] It refers to a superclass of a Java class. It redefines Class::superClass.
It is derived.
Constraints
[1] Nested classifiers belonging to a class or interface can only be of type JavaClass or JavaInterface. self.
nestedClassifier -> forAll (c | c.oclIsTypeOf (JavaClass) or c.oclIsTypeOf (JavaInterface))
[2] The implemented interfaces are those referred through the interface realization. implement = self.
interfaceRealization.contract
311
Appendix A
[3] A class that has at least one abstract method must be declared abstract. self.javaOperation -> select
(op | op.oclIsTypeOf (Method)) -> exists (m | m.oclAsType (Method).isAbstract) implies self.
isAbstract)
[4] An abstract class does not have a constructor defined explicitly. self.isAbstract implies self.javaOperation -> select (op | op.oclIsTypeOf (Constructor)) -> isEmpty ()
[5] A class that is declared final cannot have subclasses, i.e., it is not superclass of any class in the package. self.isFinal implies self.javaPackage.ownedMember -> select (m | m.oclIsTypeOf (JavaClass))
-> forAll (c| c.oclAsType (JavaClass).superClass < > self)
[6] The access level protected, private or static can only be applied to nested classes, i.e., that are
declared within the declaration of another class. (self.visibility = #protected or self.visibility =
#private or self.isStatic) implies self.javaPackage.ownedMember -> select (m | m.oclIsTypeOf
(JavaClass)) -> exists (c | c.oclAsType (JavaClass).nestedClass -> includes(self))
[7] Private methods of a class can not be declared abstract. self.javaOperation -> select (op |
op.oclIsTypeOf (Method)) -> forAll (m | m.visibility = #private implies not m.oclAsType (Method).
isAbstract)
[8] Static methods of a class can not be declared abstract. self.javaOperation -> select (op | op.oclIsTypeOf
(Method)) -> forAll (m | m.isStatic implies not m.oclAsType(Method).isAbstract)
[9] Final methods of a class can not be declared abstract. self.javaOperation -> select (op | op.oclIsTypeOf
(Method)) -> forAll (m | m.oclAsType (Method).isFinal implies not m.oclAsType (Method).
isAbstract)
[10] A class is generic if it has a signature template. isGeneric = (self.ownedTemplateSignature -> size
() =1)
[11] Parameters are derived through the parameters of the signature template. /parameters= self.
ownedTemplateSignature.parameter
[12] A class is concrete, if its methods have associated an implementation. not self.isAbstract implies
self.allMethod () -> forAll (m | self.allBody () -> exist (b | b.signature = m))
[13] Elements, that can be actual parameters of a formal parameter, are of type Java types. self.parameters.parameteredElement -> forAll (p | p.oclIsTypeOf (JavaType))
Additional Operations
[1] allMethod is the set of all methods, i.e., the methods that are own, inherited and the methods of
the interfaces implemented. allMethod (): Set(Method) allMethod () = self.allClassMethod() ->
union(self.implement.allInterfaceMethod()) allClassMethod(): Set(Method) allClassMethod () =
self.javaOperation -> select (o | o.oclIsType(Method)) -> union (self.superClass.allClassMethod
()) allInterfaceMethod (): Set (Method) allInterfaceMethod () = self.method -> union(self.superInterface.allInterfaceMethod())
[2] allBody is the set of all method implementations of a class, i.e., both own and inherited. allBody
(): Set (Implementation) allBody = self.allMethod ().body
JavaInterface
Description
It describes the characteristics of an interface according to the Java language.
312
Appendix A
Generalizations
Attributes
No additional attributes.
Associations
Constraints
[1] Interfaces are implicitly abstract. self.isAbstract
[2] The own members of an interface are implicitly public. self.ownerMember -> forAll (m | m.visibility
= #public)
[3] Nested classifiers of an interface can only be of the type JavaClass or JavaInterface. self.nestedClassifier -> forAll (c | c.oclIsTypeOf (JavaClass) or c.oclIsTypeOf (JavaInterface))
[4] An interface that is directly nested in the class declaration can only be declared private or protected. (self.visibility = #protected or self.visibility = #private) implies self.package.ownedMember
-> select (m | m.oclIsTypeOf (JavaClass)) -> exists (c | c.oclAsType(JavaClass).nestedInterface ->
includes (self))
[5] An interface that in the class or interface declaration is nested can only be declared static. self.
isStatic implies self.package.ownedMember -> select (m | m.oclIsTypeOf (JavaClass)) -> exists
(c | c.oclAsType(JavaClass).nestedInterface -> includes (self)) or self.package.ownedMember ->
select (m | m.oclIsTypeOf (JavaInterface)) -> exists (I | i.oclAsType (JavaInterface).nestedInterface
-> includes (self))
[6] Methods that are declared in an interface are abstract and hence do not have implementation. self.
method -> forAll (m| m.isAbstract and m.body -> isEmpty ())
[7] Methods of an interface can not be declared static. self.method -> forAll (m| not m.isStatic)
[8] Methods of an interface can not be synchronized. self.method -> forAll (m| not
m.isSynchronized)
313
Appendix A
[9] Fields of an interface are implicitly public, static or final. self.field -> forAll (f | f.visibility = #public
and f.isStatic and f.siFinal)
[10] superInterface is derived of the generalization. /superInterface = self.generalization.general
[11] parameters are derived through the parameters of the signature template. /parameters = self.
ownedTemplateSignature.parameter
[12] Elements that can be actual parameters of a formal parameter are types of Java. self.parameters.
parameteredElement -> forAll (p | p.oclIsTypeOf (JavaType))
JavaOperation
Description
It describes a method according to the specification of the Java language.
Generalizations
Associations
Constraints
[1] An abstract operation does not have implementation. self.isAbstract implies self.body -> isEmpty
()
JavaPackage
Description
It is a package as is defined in the Java language.
Generalizations
314
Appendix A
Attributes
No additional attributes.
Associations
javaClass: JavaClas s [*] It refers to the classes that are members of this package. It is a subset of
Package::ownedType.
javaInterface: JavaInterface [*] It refers to the interfaces that are members of this package. It is a
subset of Package::ownedType.
/subpackage: JavaPackage [*] It refers to the packages that are members of this package. It redefines Package::nestedPackage. It is derived.
Constraints
[1] Members of a package can only be classes, interfaces or sub-packages. self.ownedMember ->
forAll (m | m.oclIsTypeOf (JavaInterface) or m.oclIsTypeOf (JavaClass) or m.oclIsTypeOf
(JavaPackage))
Method
Description
It describes a method according to its definition in Java language.
Generalizations
JavaOperation
Attributes
isAbstract: Boolean [1] It specifies whether a method is abstract, i.e., without implementation.
isFinal: Boolean [1] It specifies whether a method is final. In this case, it can not be overwritten in
a derived class. It redefines RedefinableElement::isLeaf.
isNative: Boolean [1] It specifies whether a method is native.
isSyncronized: Boolean [1] It specifies whether a method is synchronized. It is true if acquires a
lock before execution.
Associations
interface: JavaInterface [0..1] It declares the interface declaring this method. It redefines
Operation::interface.
Constraints
[1] A native method can not be abstract. self.isNative implies not self.isAbstract
315
Appendix A
[2] If a method has a return type then it must have a return statement. self.type -> size () = 1 implies self.
body.block.oclIsTypeOf (Return) or self.body.block.oclIsKindOf (BlockStatement) and self.body.
block.allStatement() -> exists (sent | sent.oclIsTypeOf(Return))
Additional operations
[1] allStatement is the set of all statements that conforms the body of the method. allStatement():
Set(Statement) allStatement() = self.subBlock -> union (self.subBlock.allStatement ())
OperationParameter
Description
It specifies the parameters of an operation according to the specification of the Java language.
Generalization
Attributes
No additional attributes.
Associations
type: JavaType [1] It refers to the type of the parameter. It redefines TypedElement::type.
Constraints
No additional constraints.
Attributes
316
Appendix A
class-key: Class-Key [1] It specifies the type of the class, i.e., if it is a class, structure or union.
isFinal: Boolean [1] It specifies if the class has subclasses. It redefines
RedefinableElement::isLeaf.
/isGeneric: Boolean It specifies if the class is generic. It is a derived attribute.
Associations
variable: Variable [*] It refers to the own variables of the C++ class. It redefines
Class::ownedAttribute.
nestedClass: C++Class [*] It refers to the C++ classes that are declared within the body of a C++
class (nested classes). It is a subset of Class::nestedClassifier.
/superClass: C++Class [*] It refers to the superclasses of a C++ class. It redefines Class::superClass.
It is derived.
function: C++MemberFunction [*] It refers to the own functions of the class. It redefines
Class::ownedOperation.
generalization: C++Generalization [*] It refers to the generalizations of the class. It redefines
Class::Generalization.
friendClass: C++Class [*] It refers to the friend classes of the class.
317
Appendix A
Constraints
[1] A class that has pure virtual functions must be declared abstract. self.function -> select (oclIsTypeOf
(Method)) -> exists (m | m.oclAsType (Method).isPureVirtual) implies self.isAbstract
[2] A class declared final does not have subclasses, i. e., it is not superclass of any class belonging to
the package. self.isFinal implies self.package.ownedMember -> select (oclIsTypeOf (C++Class))
-> forAll (c | c.oclAsType (C++Class).superClass < > self)
318
Appendix A
[3] Private functions of a class can not be declared abstract. self.function -> select (oclIsTypeOf (Method))
-> forAll (m | m.visibility = #private implies not m.oclAsType (Method).isPureVirtual)
[4] Final methods of a class can not be declared abstracts. self.function -> select (oclIsTypeOf (Method))
-> forAll (m | m.oclAsType (Method).isFinal implies not m.oclAsType (Method).isVirtual)
[5] A class is generic if it has a signature template. isGeneric = (self.ownedTemplateSignature -> size
() =1)
[6] Parameters are derived from parameters of the signature template that is redefinable. /parameters
= self.ownedTemplateSignature.parameter
[7] Friend functions are C++ functions but no member functions of a class. self.friendFunction ->
forAll (f | f.isTypeOf (C++Function))
[8] A class only has a destructor. self.function -> select (oclIsTypeOf (Destructor)) ->size() <=1
C++File
Description
It represents a C++ file.
Generalizations
Attributes
extension: FileExtension [1] It specifies the extension of the file, i.e., if the file is header then h,
else, if it is an implementation c or cpp.
319
Appendix A
Associations
c++Project: C++Project [1] It refers to the project of which the file is part.
/includedFile: C++File [*] It refers to the set of files that are included. It is derived.
globalVariableandConstantDeclaration:GlobalVariableandConstantDeclaration[*] It refers to the
set of global variables and constants that are declared.
precompilerDirectives: PrecompilerDirectives [*] It refers to the set of precompiler directives.
classifierDeclaration: ClassifierDeclaration [*] It refers to the set of classifier declarations.
classifierDefinition: ClassifierDefinition [*] It refers to the set of classifier definitions.
functionDeclaration: FunctionDeclaration [*] It refers to the set of function declarations.
functionDefinition: FunctionDefinition [*] It refers to the set of function definitions.
Constraints
[1] The included files are derived through the files that are included by the directive #include. /includedFile = self.precompilerDirective -> collect (oclIsTypeOf (Include).headerFile)
C++Function
Description
It is a C++ function.
Generalizations
320
Appendix A
Attributes
isVarArg: Boolean It specifies whether the function can have variable arguments.
linkage: Linkage-Specifier It specifies whether the function is extern, indicating to compiler that
the definition of the function is in another file, or is static, i.e., its name is invisible on the outside
of the file declaring it.
isInLine: Boolean True means that the compiler will replace the function call by the function
code.
Associations
redefines
redefines
redefines
redefines
321
Appendix A
Figure 26.
throws: C++Class [*] It refers to the types that represent exceptions that can appear during an
invocation of this operation. It redefines Operation::raisedException.
body: Implementation [0..1] It refers to the implementation of the function.
Constraints
[1] A pure virtual function does not have implementation. self.isPureVirtual implies self.body ->
isEmpty()
C++ Generalization
Description
It represents a generalization in C++.
Generalizations
Attributes
322
access-specifier: Access-Specifier It specifies what the access type of the members of the base
class.
isVirtual: Boolean It specifies whether the inheritance is virtual.
Appendix A
Associations
general: C++Class [1] It refers to the more general class in the generalization. It redefines
Generalization::general.
specific: C++Class [1] It refers to the more specific class in the generalization. It redefines
Generalization::specific.
Constraints
No additional constraints.
C++MemberFunction
It is a function that is member of a C++ class.
Generalizations
C++Function
Attributes
No additional attributes.
Associations
class: C++Class [1] It refers to the class to which the function belongs. It redefines
Operation::class.
Constraints
[1] A function that is member of a class can not be declared extern. self.linkage <> extern
C++Project
Description
It represents a C++ project.
Generalizations
Attributes
No additional attributes.
323
Appendix A
Associations
c++File: C++File [1.. *] It refers to the set of C++ files that belong to the project.
Constraints
No additional constraints.
ClassifierDeclaration
Description
It represents classifier declarations.
Generalizations
Attributes
No additional attributes.
Associations
Constraints
No additional constraints.
ClassifierDefinition
Description
It denotes classifier definitions.
Generalizations
Attributes
No additional attributes.
Associations
Constraints
No additional constraints.
324
Appendix A
Constructor
Description
It designs a function that is used to create class instances. It cannot be called explicitly by means of
invocation expression. It does not have return type. Its name is the same of the class including it. Its
declaration is no inherited.
Generalizations
C++MemberFunction
Attributes
No additional attributes.
Associations
No additional associations.
Constraints
[1] Constructors do not have return type. self.type -> isEmpty()
[2] The name of the constructor is the same as the class name including its declaration. self.name =
self.class.name
Destructor
Description
A destructor is a function member with the same name as the class prefixed by a ~. Classes have
only a function destructor that does not have arguments nor return type. Destructors are usually used
to de-allocate memory and do other cleanup for a class object and its class members when the object
is destroyed.
Generalizations
C++MemberFunction
Attributes
isVirtual: Boolean [1] It specifies whether the destructor is virtual, i.e., if it can be redefined in the
subclasses.
Associations
No additional associations.
325
Appendix A
Constraints
[1] A destructor does not have arguments nor return type. self.ownedParameter -> isEmpty () and self.
type -> isEmpty ()
[2] The destructor name is the same as the name of the class containing it prefixed by a ~. self.name
= ~.concat (self.class.name)
FunctionDeclaration
Description
It denotes function declarations.
Generalizations
Attributes
No additional attributes.
Associations
Constraints
No additional restrictions.
FunctionDefinition
Description
It represents function definitions.
Generalizations
Attributes
No additional attributes.
Associations
Constraints
No additional constraints.
326
Appendix A
GlobalVariableandConstantDeclaration
Description
It denotes global variables and constants that are declared in a C++ file.
Generalizations
Attributes
No additional attributes.
Associations
No additional associations.
Constraints
No additional constraints.
HeaderFile
Description
It represents a C++ header file.
Generalizations
C++File
Attributes
No additional attributes.
Associations
No additional associations.
Constraints
No additional constraints.
Implementation
Description
It specifies a procedure that carries out the function result.
Generalization
327
Appendix A
Attributes
Associations
Constraints
No additional constraints.
ImplementationFile
Description
It denotes a C++ implementation file.
Generalizations
C++File
Attributes
No additional attributes.
Associations
No additional associations.
Constraints
No additional constraints.
Include
Description
It denotes precompiler directives of type #include.
Generalizations
PrecompilerDirective
Attributes
No additional attributes.
328
Appendix A
Associations
headerFile: HeaderFile [1] It denotes the header file that is included through a directive.
Constraints
No additional constraints.
Method
Description
It declares a member function of a class that can be called by passing a fixed number of arguments.
Generalizations
C++MemberFunction
Attributes
Associations
No additional associations.
Constraints
No additional restrictions.
PrecompilerDirective
Description
It denotes precompiler directives.
Generalizations
Attributes
No additional attributes.
329
Appendix A
Associations
No additional associations.
Restrictions
No additional restrictions.
Statement
Description
It denotes the code block that implements a function.
Generalizations
Attributes
No additional attributes.
Associations
Constraints
No additional constraints.
Variable
Description
It denotes the variable that is declared in the class.
Generalizations
Attributes
330
isConst: Boolean [1] It specifies whether a variable is constant. If it is final, must have an initial
value compulsory. It redefines RedefinableElement::isLeaf.
Appendix A
isVolatile: Boolean [1] It specifies whether a variable is volatile, i.e., if it is not accessed
synchronically.
storage: Storage-Specifier [1] It specifies the type of the variable allocation.
var-type: Var-Type [1] It specifies the type of the variable, i.e., if the variable is object, reference
or pointer.
Associations
class: C++Class [1] It refers to a class declaring this variable. It redefines Property::class.
Constraints
[1] A variable is a property that is part of a class and is not member of associations. self.class -> size
() = 1 and self.association -> isEmpty () and self.opposite -> isEmpty ()
331
332
Appendix B:
This Appendix includes the specification of the type system of OCL. It includes the OCL signature and
the algebraic specification.
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
Appendix B
not: Boolean
True if self is false.
post: if self then result = false else result = true endif
implies (b: Boolean): Boolean
True if self is false, or if self is true and b is true.
post: (not self) or (self and b)
1. 1. 2. NEREUS Signature
TYPE Boolean
OPERATIONS
True: Boolean
False: Boolean
not_: Boolean Boolean
_and_: Boolean x Boolean Boolean
_=_: Boolean x Boolean Boolean
_or_: Boolean x Boolean Boolean
_xor_: Boolean x Boolean Boolean
__: Boolean x Boolean Boolean
_:_ Boolean x Boolean Boolean
if_then_else: Boolean x Boolean x Boolean Boolean
1. 2. real
1. 2. 1. OCL Signature
Integer is a subclass of Real
+ (r: Real): Real
The value of the addition of self and r.
- (r: Real): Real
The value of the subtraction of r from self.
* (r: Real): Real
The value of the multiplication of self and r.
-: Real
The negative value of self.
333
Appendix B
1. 2. 2. NEREUS Signature
TYPE Real
OPERATIONS
_=_: Real x
_< >_: Real
-_: Real ->
_+_: Real x
_-_: Real x
_*_: Real x
334
Real
x Real
Real
Real
Real
Real
Boolean
Boolean
Real
Real
Real
Appendix B
1. 3. integer
1. 3. 1. OCL Signature
-: Integer
The negative value of self.
+ (i: Integer): Integer
The value of the addition of self and i.
- (i: Integer): Integer
The value of the subtraction of i from self.
* (i: Integer): Integer
/ (i: Integer): Real
The value of self divided by i.Evaluates to OclInvalid if r is equal to zero.
abs (): Integer
The absolute value of self. post: if self < 0 then result = - self else result = self endif
div (i: Integer): Integer
The number of times that is completely within self. pre: i <> 0 post: if self / i >= 0 then result = (self /
i).floor () else result = -((-self/i).floor ()) endif
mod (i: Integer): Integer
The result is self modulo i. post: result = self - (self.div (i) * i)
max (i: Integer): Integer
The maximum of self an i. post: if self >= i then result = self else result = i endif
335
Appendix B
1. 3. 2 NEREUS Signature
TYPE Integer
OPERATIONS
_=_: Integer x Integer Boolean
_< >_: Integer x Integer Boolean
-_: Integer Integer
_+_: Integer x Integer Integer
_-_: Integer x Integer Integer
_*_: Integer x Integer Integer
_/_: Integer x Integer Integer
abs: Integer Integer
floor: Integer Integer
round: Integer Integer
max: Integer x Integer Integer
min: Integer x Integer Integer
_<_: Integer x Integer Boolean
_>_: Integer x Integer Boolean
_<=_: Integer x Integer Boolean
_>=_: Integer x Integer Boolean
1. 4. String
1. 4. 1. OCL Signature
size (): Integer
The number of characters in self.
Concat (s: String): String
The concatenation of self and s. post: result.size () = self.size () + string.size () post: result.substring
(1, self.size ()) = self post: result.substring (self.size () + 1, result.size ()) = s
substring(lower: Integer, upper: Integer): String
The sub-string of self starting at character number lower, up to and including character number upper.
Character numbers run from 1 to self.size (). pre: 1 <= lower pre: lower <= upper pre: upper <= self.
size ()
336
Appendix B
1. 4. 2. NEREUS Signature
TYPE String
OPERATIONS
concat: String x String String
size: String Integer
subString: String x Integer x Integer String
toInteger: String Integer
toReal: String -> Real
1. 5. tuple
CLASS Tuple
IMPORTS T1, T2
EFFECTIVETYPE
Tuple
OPERATIONS
createTuple: T1 x T2 Tuple
modifFirst: Tuple x T1 Tuple
modifSecond: Tuple x T2 Tuple
selectFirst: Tuple T1
selectSecond: Tuple T2
AXIOMS t: Tuple; f1, f2: T1; s1, s2: T2
modifFirst (createTuple (f1, s1), f2) = createTuple (f2, s1)
modifSecond (createTuple (f1, s1), s2) = createTuple (f1, s2)
selectFirst (createTuple(f1,s1)) = f1
selectSecond (createTuple(f1,s1)) = s1
END-CLASS
337
Appendix B
338
Appendix B
2. 1. 2. NEREUS Specification
CLASS Collection [Elem: ANY]
IMPORTS Boolean, Nat
GENERATED-BY create, add DEFERREDTYPES
Collection
OPERATIONS
create: Collection
add: Collection x Elem Collection
count: Collection x Elem Nat
collect: Collection x (Elem Elem1: ANY) Collection
EFFECTIVEOPERATIONS isEmpty: Collection Boolean
size: Collection Nat
includes: Collection x Elem Boolean
excludes: Collection x Elem Boolean
includesAll: Collection x Collection Boolean
forAll: Collection x (Elem Boolean) Boolean
exists: Collection x (Elem Boolean) Boolean
select: Collection x (Elem Boolean) Collection
reject: Collection x (Elem Boolean) Collection
iterate: Collection x (Elem x Acc: ANY) x ( Acc) Acc
AXIOMS c, c1: Collection; e: Elem; f: Elem Boolean; g: Elem x Acc
Acc;
base: Acc
isEmpty (c) = (size (c) = 0)
iterate (create, g, base) = base
iterate (add (c, e), g, base)= g (e, iterate (c, g, base))
count (c, e) = iterate (c, f1, 0)
WHERE OPERATIONS f1: Elem x NatNat
AXIOMS e1: Elem; i: Nat
f1 (e1, i) = if e = e1 then i + 1 else i
END-WHERE
size (create) = 0
size (add (c, e)) = 1 ] + size (c)
includes (create, e) = False
includes (add (c, e), e1) = if e = e1 then True else includes (c,
e1)
excludes (create, e) = True
excludes (add (c, e), e1) = if e = e1 then False else excludes (c,
e1)
includesAll (create, c) = True
includesAll (add (c, e), c1) = includesAll (c, c1) and includes (e,
c1)
excludesAll (create, c) = True
339
Appendix B
excludesAll (add (c, e), c1) = excludesAll (c, c1) and excludes (e,
c1)
forAll (create, f) = True
forAll (add (c, e), f) = f (e) and forAll (c, f)
exists (create, f) = False
exists (add (c, e), f) = f (e) or exists (c, f)
select (create, f) = create
select (add (c, e), f) = if f (e) then add (select (c, f), e) else
select (c, f)
reject (create, f) = create
reject (add (c, e), f) = if not f (e) then add (reject (c, f),e)
else reject (c, f)
END-CLASS
Collection-with-suma
CLASS Collection-with-suma [Elem: Real]
INHERITS Collection [Elem]
EFFECTIVEOPERATIONS
suma: Collection-with-suma Real
AXIOMS c: Collection-with-suma
suma (c) = iterate (c, f, 0)
WHERE OPERATIONS
f: Real x Real Real
AXIOMS r1, r2: Real
f (r1, r2) = r1 + r2
END-WHEREEND-CLASS
Collection-with-cartesian-product
CLASS Collection-with-cartesianProduct [Elem1, Elem2]IS-SUBTYPE-OF
Collection [Elem1] [Collection: Collection-with-cartesianProduct]
IMPORTS Collection [Elem2], Tuple [Elem1, Elem2], Set [Tuple] [set:
setTuple]
EFFECTIVEOPERATIONS
product: Collection-with-cartesianProduct x Collection SetTuple
AXIOMS c: Collection-with-cartesianProduct; c2: Collection; t: tuple; s: SetTuple
product (c, c2) = iterate (c, g, base)
WHERE OPERATIONS
g: Element x setTuple setTuple
base: setTupla
AXIOMS e: Element; acc: setTuple
g (e, acc) =
340
Appendix B
2. 2. Set
2. 2. 1. OCL Signature
union (s: Set (T)): Set (T)
The union of self and s. post: result -> forAll (elem | self -> includes (elem) or s -> includes (elem)) post:
self -> forAll (elem | result -> includes (elem)) post: s -> forAll (elem | result -> includes (elem))
union(bag: Bag(T)): Bag(T)
The union of self and bag.
post: result -> forAll (elem | result -> count (elem) = self -> count (elem) + bag -> count (elem)) post:
self -> forAll (elem | result -> includes (elem)) post: bag -> forAll (elem | result -> includes (elem))
341
Appendix B
342
Appendix B
2. 2. 2. Nereus Specification
CLASS Set [T: ANY]
IS-SUBTYPE-OF Collection [T] [create: createSet; add: including]
IMPORTS Sequence, Bag [create: createBag; including: includingBag],
OrderedSet
GENERATED-BY createSet, including EFFECTIVETYPES
Set
OPERATIONS createSet, including, count
equal: Set x Set Boolean
union: Set x Set Set
union: Set x Bag Bag
intersection: Set x Set Set
intersection: Set x Bag Set
: Set x Set Set
excluding: Set x T Set
symmetricDifference: Set x Set Set
collect: Set x (T T1: ANY) Bag [T1]
flatten: Set Set [T1: ANY]
asSet: Set Set
asOrderedSet: Set OrderedSet
asSequence: Set Sequence
asBag: Set Bag
AXIOMS s, s2: Set; b: Bag; b1: Bag [T1] ; e, e1: T; g: T1 Boolean
collect (createSet, g) = createBag
collect (including (s, e), g) = includingBag (collect (excluding (s,
e),g (e))
count (s, e) <= 1
forAll (v) (union (s, s2), [includes (s, v) or includes (s2, v)])
forAll (v) (s, [ includes (union (s, s2), v) ])
forAll (v) (s2, [ includes (union (s, s2), v) ])
forAll (v) (s, [ includes (union (s, b), v) ])
343
Appendix B
344
Appendix B
2. 3. Bag
2. 3. 1. OCL Signature
= (bag: Bag (T)): Boolean
True if self and bag contain the same elements, the same number of times. post: result = (self -> forAll
(elem | self -> count (elem) = bag -> count (elem)) and bag -> forAll (elem | bag -> count(elem) = self
-> count(elem)))
union (bag: Bag (T)): Bag (T)
The union of self and bag. post: result -> forAll (elem | result -> count (elem) = self -> count (elem) +
bag -> count (elem)) post: self -> forAll (elem | result -> count (elem) = self -> count (elem) + bag ->
count (elem)) post: bag -> forAll (elem | result -> count (elem) = self -> count (elem) + bag -> count
(elem))
union (set: Set (T)): Bag (T)
The union of self and set. post: result -> forAll (elem | result -> count (elem) = self -> count (elem) + set
-> count (elem)) post: self -> forAll (elem | result -> count (elem) = self -> count (elem) + set -> count
(elem)) post: set -> forAll(elem | result -> count (elem) = self -> count (elem) + set -> count (elem))
intersection (bag: Bag (T)): Bag (T)
The intersection of self and bag. post: result -> forAll (elem | result -> count (elem) = self -> count (elem).
min (bag -> count (elem))) post: self -> forAll (elem | result -> count (elem) = self -> count (elem).min
(bag -> count (elem))) post: bag -> forAll(elem | result -> count (elem) = self -> count (elem).min (bag
-> count (elem)))
intersection (set: Set (T)): Set (T)
The intersection of self and set. post: result -> forAll (elem | result -> count (elem) = self -> count (elem).
min (set -> count (elem))) post: self -> forAll (elem | result -> count (elem) = self -> count (elem).min
(set -> count (elem))) post: set -> forAll (elem | result -> count (elem) = self -> count (elem).min (set
-> count (elem)))
including (object: T): Bag (T)
The bag containing all elements of self plus object.
post: result -> forAll (elem |
if elem = object then result -> count(elem) = self -> count(elem) + 1
else result -> count(elem) = self -> count(elem)
endif)
post: self -> forAll (elem |
if elem = object then result -> count (elem) = self -> count (elem) + 1
else result -> count(elem) = self -> count(elem)
endif)
345
Appendix B
2. 3. 2. NEREUS Specification
CLASS Bag [T]
IS-SUBTYPE-OF Collection [T] [create: createBag; add: including]
IMPORTS Sequence [T], Set [T]
GENERATED-BY createBag, including
EFFECTIVETYPES Bag
346
Appendix B
OPERATIONS
emptyBag, including, count
equal: Bag x Bag Boolean
union: Bag x Bag Bag
union: Bag x Set Bag
intersection: Bag x Bag Bag
intersection: Bag x Set Set
excluding: Bag x T Bag
collect: Bag x (T T1) Bag [T1]
asBag: Bag -> Bag
flatten: Bag -> Bag [T1:ANY]
asSequence: Bag Sequence
asSet: Bag Set
asOrderedSet: Bag OrderedSet
AXIOMS b, b1: Bag; s: Set; e, e1: T; g: T T1; f: T Boolean
count (including (b, e), e1) = if e = e1 then 1 + count (b, e1) else
count (b, e1)
equal (b, b1) = forAll (v) (b, [count (b, v) = count (b1, v) and
forAll (v1) (b1, count (b1, v) = count (b, v) ])
forAll (v) (union (b, b1), [count (union (b, b1), v) = count (b, v)
+ count (b1, v) ])
forAll (v) (b, [count (union (b, b1), v) = count (b, v) + count (b1,
v) ])
forAll (v) (b1, [count (union (b, b1), v) = count (b, v) + count
(b1, v) ])
forAll (v) (union(b, s), [count (union(b, s), v) = count (b, v) +
count (s, v) ])
forAll (v) (b, [count (union (b, s), v) = count (b, v) + count (s,
v) ])
forAll (v) (s, [count (union (b, s), v) = count (b, v) + count (s,
v) ])
forAll (v) (intersection (b, b1),
[count (intersection (b, b1), v) = min (count (b, v), count (b1,
v) ])
forAll (v) (b, [count (intersection (b, b1), v) = min (count(b, v),
count (b1, v) ])
forAll (v) (b1, [count (intersection (b, b1), v) = min (count (b,
v), count (b1, v) ])
forAll (v) (intersection (b, s), [count(intersection(b,s),v) =
min(count(b,v), count(s,v)])
forAll (v) (b, [count (intersection (b, s), v) = min (count (b, v),
count (s, v) ])
forAll (v) (s, [count (intersection (b, s), v) = min (count (b, v),
count (s, v) ])
347
Appendix B
2. 4. Sequence
2. 4. 1 OCL Specification
count (object: T): Integer
The number of occurrences of object in self.
= (s: Sequence (T)): Boolean
True if self contains the same elements as s in the same order. post: result = Sequence {1..self -> size ()
} -> forAll (index: Integer | self -> at (index) = s -> at (index)) and self -> size () = s -> size ()
union (s: Sequence (T)): Sequence (T)
The sequence consisting of all elements in self, followed by all elements in s. post: result -> size () = self
-> size () + s -> size () post: Sequence {1..self -> size () } -> forAll (index: Integer | self -> at (index) =
result -> at (index)) post: Sequence {1..s -> size () } -> forAll (index: Integer | s -> at (index) = result
-> at (index + self -> size ())))
348
Appendix B
349
Appendix B
2. 4. 2. NEREUS Specification
CLASS Sequence [T]
IMPORTS Bag [T], Set [T], Integer
IS-SUBTYPE-OF Collection [create: createSeq; add: append]
GENERATED-BY createSeq, append
EFFECTIVE TYPES Sequence
OPERATIONS
createSeq, append, count
equal: Sequence x Sequence
prepend: Sequence x T Sequence
union: Sequence x Sequence Sequence
flatten: Sequence Sequence [T1: ANY]
insertAt: Sequence x Integer x T Sequence
subSequence:
350
Appendix B
Appendix B
(index + 1 <= i <= size (s)) implies at (s, i) = at (insertAt(s, index, e), i + 1)
size (subSequence (s, lower, upper)) = upper lower + 1
(lower <= index <= upper) implies
at (subsequence (s, lower, upper), index lower +1) = at (sequence,
index)
at (s, indexOf (s, e)) = e
first (s) = at (s,1)
last (s) = at (s, size (s))
including(s, e) = append(s, e)
not includes (excluding (s, e), e)
size (excluding (s, e)) = size (s) count (s, e)
iterate (v) (s, [if e = v then acc else append (acc, v) ], [acc =
createSeq])
excluding (create, e) = create
excluding (append (s, e), e1) = if e = e1 then excluding (s, e)
else append (excluding (s, e), e1)
forAll (v) (asBag (s), [count (s, v)) = count (asBag (s), e) ])
forAll (v) (s, [count (s, v) = count (asBag (s), v) ])
asSequence (s) = s
forAll (v) (asSet (s), [includes (s, v)])
forAll (v) (asset (s), [includes (asset (s), v) ])
forAll (v) (asOrderedSet (s), [includes (s, v) ])
forAll (v) (s, [includes (asOrderedSet (s), v) ])
forAll (v) (s, [count (isOrderdSet (s), e) = 1)
forAll (v1, v2) (s, [(indexOf (s, v1) < indexOf (s, v2)) implies
(indexOf (isOrderedSet (s), v1) < indexOf (isOrderedSet (s), v2) ])
collect (createSeq, g) = createSeq
collect (append (s, e), g) = including (collect (excluding (s, e),
g(e))
END-CLASS
2. 5. Ordered Set
2. 5. 1. OCL Specification
append (object: T): OrderedSet (T)
The set of elements, consisting of all elements of self, followed by object. post: result -> size () = self
-> size () + 1 post: result -> at (result -> size ()) = object post: Sequence {1..self -> size() } -> forAll
(index: Integer | result -> at (index) = self -> at (index))
352
Appendix B
2. 5. 2. NEREUS Specification
CLASS OrderedSet [T: ANY]
IMPORTS Integer, Bag
IS-SUBTYPE-OF Collection [create: createOrderedSet; add: append]
GENERATED-BY createOrderedSet, including
EFFECTIVE TYPES OrderedSet
OPERATIONS
createOrderedSet, append, count
prepend: OrderedSet x T OrderedSet
insertAt: OrderedSet x Integer x T OrderedSet
subOrderedSet:
OrderedSet (s) x Integer (lower) x Integer (upper) OrderedSet
pre: 1<= lower and lower <= upper and upper <= size (s)
at: OrderedSet (s) x Integer (i) T
pre: i >=1 and I <= size (s)
353
Appendix B
354
Appendix B
3. 2. nereuS Specification
CLASS EnumType
IMPORTS String, OrderedSet [String], Nat
GENERATED-BY createEnumType
EFFECTIVETYPES
EnumType
OPERATIONS
createEnumType: OrderedSet EnumType
cardinality: EnumType Nat
value: EnumType (t) x Nat (i) String
pre: 1<= i <= cardinality (t)
AXIOMS t: EnumType; s: OrderedSet; i: Nat
cardinality (createEnumType (s)) = size (s)
value (s, i) = at (s, i)
END-CLASS
Appendix B
.... 1i n
select-i: Cartes-Prod Ti
AXIOMS cp: CartesProd; t1:T1; t2, t2:T2... tn:Tn
modif-i (Create(t1, t2,.ti,.., tn)) = ti
...
select-i (create(t1, t2, .., ti,.. tn), ti) = create(t1, t2,.., ti,..
tn) 1i n
END-CLASS
4. 2. 2. Unidirectional- Effective/ 1 to 1
RELATION SCHEME Unidirectional-1
--Unidirectional/ 1 to 1
IS-SUBTYPE-OF BinaryAssociation
GENERATED-BY create, addLink
EFFECTIVETYPES Unidirectional-1
OPERATIONS
name, frozen, changeable, addOnly, get_role1, get_role2, getMult1,
getMult2, getVisibility1, getVisibility2
create: TypeName Unidirectional-1
addLink: Unidirectional-1 (u) x Class1 (c1) x Class2 (c2) Unidirectional-1
356
Appendix B
pre: not frozen (u) and not isRelated (u, c1, c2) and rightCardinality (u, c1) < 1 and leftCardinality (u, c2) < 1
removeLink: Unidirectional-1 (u) x Class1 (c1) x Class2 (c2) Undirectional-1
pre: isRelated (u, c1, c2) and not addOnly (u) and not frozen (u)
get_Class2: Unidirectional-1(u) x Classl (c1) Class2pre: isRightLinked (u, c1)
isRelated: Unidirectional-1 x Class1 x Class2 Boolean
isRightLinked: Unidirectional-1 x Class1 Boolean
isLeftLinked: Unidirectional-1 x Class2 Boolean
isEmpty: Unidirectional-1 Boolean
rightCardinality: Unidirectional-1 x Class1 Nat
leftCardinality: Unidirectional-1x Class2 Nat
AXIOMS t: TypeName; u: Unidirectional-1; c1, cc1: Class1; c2, cc2:
Class2
get-role1 (u) = <role name>
get_role2 (u) = <role name>
getVisibility1 (u) = <visibility>
getVisibility2 (u) = <visibility>
frozen (u) = <True or False>
changeable (u) =<True or False>
addOnly (u) =<True or False>
getMult1(u) = 1
getMult2 (u) = 1
isRelated (create (t), c1, c2) = False
isRelated (addLink (u, c1, c2), cc1, cc2) =
(cc1 = c1 and cc2 = c2) or isRelated (u, cc1, cc2)
get_Class2 (addLink (u, c1, c2), cc1) =
if c1 = cc1 then c2 else get_Class2 (u, cc1)
removeLink (addLink (u, c1, c2), cc1, cc2) =
if c1 = cc1 and c2 = cc2 then u else addLink(removeLink (u, cc1,
cc2), c1, c2)
name (create (t)) = t
name (addLink (u, c1, c2))= name (u)
isEmpty (create (t)) = True
isEmpty (addLink (u, c1, c2)) = False
isRightLinked (create (t), c1) = False
isRightLinked(addLink (u, c1, c2), cc1) = (c1 = cc1) or isRightLinked (u, cc1)
isLeftLinked (create (t), c2) = False
isLeftLinked (addLink (u, c1, c2), cc2) = (c2 = cc2) or isLeftLinked
(u, cc2)
0 rightCardinality (u, c1) 1
0 leftCardinality (u, c2) 1
357
Appendix B
4. 2. 3. Unidirectional/ Effective/ 1 to M
RELATION SCHEME Unidirectional-2
--Unidirectional/ 1to M
IMPORTS Collection-C2: Collection [Class2] [create-c2: create]
IS-SUBTYPE-OF BinaryAssociation
GENERATED-BY create, addLink
EFFECTIVETYPES Unidirectional-2
OPERATIONS
name, frozen, changeable, addOnly, get_role1, get_role2, getMult1,
getMult2, getVisibility1, getVisibility2
create: TypeName Unidirectional-2
addLink: Unidirectional-2 (u) x Class1 (c1) x Class2 (c2) Unidirectional-2
pre: not frozen (u) and not isRelated (u, c1, c2) and leftCardinality (u, c2) < 1
and rightCardinality (u, c1) < <M>
removeLink: Unidirectional-2 (u) x Class1 (c1) x Class2 (c2) Undirectional-2
pre: isRelated (u, c1, c2) and not addOnly (u) and not frozen (u)
get_Class2: Unidirectional-2 x Class1 Collection-C2
isRelated: Unidirectional-2 x Class1 x Class2 Boolean
isRightLinked: Unidirectional-2 x Class1 Boolean
isLeftLinked: Unidirectional-2 x Class2 Boolean
isEmpty: Unidirectional-2 Boolean
rightCardinality: Unidirectional-2 x Class1 Nat
leftCardinality: Unidirectional-2 x Class2 Nat
AXIOMS t: TypeName; u: Unidirectional-2; c1, cc1: Class1; c2, cc2:
Class2
get_role1 (u) = <role name>
get_role2 (u) = <role name>
getVisibility1 (u) = <visibility>
getVisibility2 (u) = <visibility>
frozen (u) = False
changeable (u) =<True or False>
addOnly (u) =<True or False>
358
Appendix B
getMult1 (u) = 1
getMult2 (u) = <multiplicity>
isRelated (create (t), c1, c2) = False
isRelated (addLink (u, c1, c2), cc1, cc2) =
(cc1 = c1 and cc2 = c2) or isRelated (u, cc1, cc2)
get_Class2 (create (t), c1) = create-c2
get_Class2 (addLink (u, c1, c2), cc1) =
if c1 = cc1 then add (get_Class2 (u, cc1), c2) else get_Class2 (u,
cc1)
removeLink (addLink (u, c1, c2), cc1, cc2) =
if c1 = cc1 and c2 = cc2 then u else addLink (removeLink (u, cc1,
cc2), c1, c2)
name (create (t)) = t
name (addLink (u, c1, c2)) = name (u)
isEmpty (create (t)) = True
isEmpty (addLink (u, c1, c2)) = False
isRightLinked (create (t), c1) = False
isRightLinked (addLink (u, c1, c2), cc1) = (c1 = cc1) or isRightLinked (u, cc1)
isLeftLinked (create (t), c2) = False
isLeftLinked (addLink (u, c1, c2), cc2) = (c2 = cc2) or isLeftLinked
(u, cc2)
rightCardinality (create (t), c1) =0
leftCardinality (create (t), c2) = 0
rightCardinality (addLink (u, c1, c2), cc1) =
if c1 = cc1 then 1 + rightCardinality (u, cc1) else rightCardinality
(u, cc1)
leftCardinality (addLink (u, c1, c2), cc2) =
if c2 = cc2 then 1 else leftCardinality (u,cc2)
END-RELATION
Appendix B
4. 2. 5. Aggregation
RELATION SCHEME AggregationIS-SUBTYPE-OF BinaryAssociation [Whole:
Class1, Part: Class2]
DEFERREDOPERATIONS
isPart: Aggregation x Whole x Part Boolean
isEmpty: Aggregation Boolean
isLinkedWhole: Aggregation x Whole Boolean
isLinkedPart: Aggregation x Part Boolean
END-RELATION
360
Appendix B
Appendix B
= w1 or isLinkedWhole (a,
= p1) or isLinkedPart (a,
w1)
p1)
Appendix B
363
Appendix B
Appendix B
4. 2. 9. Aggregation/Simple/1 to 1/frozen
RELATION SCHEME Aggregation-4
-- aggregation/simple/ 1 to 1/frozen
IS-SUBTYPE-OF Aggregation
GENERATED-BY create, addPart
EFFECTIVETYPES Aggregation-4
OPERATIONS
name, frozen, changeable, addOnly, get_role1, get_role2, getMult1,
getMult2, getVisibility1, getVisibility2, isPart, isEmpty, isLinkedWhole, isLinkedPart
create: TypeName Aggregation-4
addPart: Aggregation-4 (a) x Part (p) x Whole (w) Aggregation-4
pre: not isPart (a, w, p)
getPart: Aggregation-4 (a) x Whole (w) Partpre: isLinkedWhole (a,
w)
getWhole: Aggregation-4 (a) x Part (p) Wholepre: isLinkedPart (a,
p)
AXIOMS a: Aggregation-4; p, p1: Part; w, w1: Whole; t: TypeName
name (create (t)) = t
name (addPart (a, p, w)) = name (a)
frozen (a) = True
changeable (a) = False
addOnly (a) = False
getMult1 (a) = 1
getMult2 (a) = 1
get_role1 (a) = <name-role1>
get_role2 (a) = <name-role2>
getVisibility1 = <visibility>
getVisibility2 = <visibility>
isPart (create (t), w, p) = False
isPart (addPart (a, p, w), w1, p1) = (w = w1 and p = p1) or isPart
(a, w1, p1)
365
Appendix B
Appendix B
Appendix B
Appendix B
(a, w1)
isLinkedPart (create (t), p1) = False
isLinkedPart (addPart(a, cp, w), p) = includes (cp, p) or isLinkedPart (a, p)
END-RELATION
Appendix B
Appendix B
Appendix B
372
Appendix B
4. 15. Bidirectional / 1 to 1
RELATION SCHEME Bidirectional-1
IS-SUBTYPE-OF BinaryAssociation
GENERATED-BY create, addLink
EFFECTIVE
name, frozen, changeable, addOnly, get_role1, get_role2, getMult1,
getMult2, getVisibility1, getVisibility2
create: Typename Bidirectional-1
addLink: Bidirectional-1(b) x Class1(c1) x Class2(c2) Bidirectional-1
pre: rightCardinality (b, c1) < 1 and leftCardinality (b, c2) < 1
and
not isRelated (a, c1, c2)
isEmpty: Bidirectional-1 Boolean
isRightLinked: Bidirectional-1 x Class1 Boolean
isLeftLinked: Bidirectional-1 x Class2 Boolean
rightCardinality: Bidirectional-1 x Class1 Nat
leftCardinality: Bidirectional-1 x Class2 Nat
getClass1: Bidirectional-1(a) x Class1 (c1) Class2pre: isRightLinked (a,c1)
getClass2: Bidirectional-1(a) x Class2 (c2) Class1pre:
isLeftLinked (a, c2)
remove: Bidirectional-1 (a) x Class1 (c1) x Class2 (c2) Bidirectional-1
pre: isRelated (a, c1, c2)
isRelated: Bidirectional-1 x Class1 (c1) x Class2 (c2) Boolean
AXIOMS a: Bidirectional-1; c1, cc1: Class1; c2, cc2: Class2; t:
TypeName
name (create(t)) = t
name (add (a, c1, c2)) = name (a)
isEmpty (create(t) = True
isEmpty (addLink (a, c1, c2)) = False
frozen (a) = <True or False>
changeable (a) = <True or False>
addOnly (a) = <True or False>
get_role1 (a) = <role name>
get_role2 (a) = <role name>
getMult1(a) = <multiplicity>
getMult2 (a) = <multiplicity>
getVisibility1 (a) = <visibility>
getVisibility2 (a) = <visibility>
isRelated (create (t), c1, c2) = False
isRelated (addLink (a, c1, c2), cc1, cc2) =
373
Appendix B
4. 16. Bidirectional/ 1 to *
RELATION SCHEME Bidirectional-2
IMPORTS Collection-C2: Collection [Class2]
IS-SUBTYPE-OF BinaryAssociation
GENERATED-BY create, addLink
EFFECTIVEOPERATIONS
name, frozen, changeable, addOnly, get_role1, get_role2, getMult1,
getMult2, getVisibility1, getVisibility2
create: Typename Bidirectional-2
addLink: Bidirectional-2 (b) x Class1 (c1) x Class2 (c2) Bidirectional-2
pre: leftCardinality (b, c2) < 1 and not isRelated (a, c1, c2)
isEmpty: Bidirectional-2 Boolean
isRightLinked: Bidirectional-2 x Class1 Boolean
isLeftLinked: Bidirectional-2 x Class2 Boolean
rightCardinality: Bidirectional-2 x Class1 Nat
leftCardinality: Bidirectional-2 x Class2 Nat
getClass1: Bidirectional-2 (a) x Class1 (c1) Collection-C2
pre: isRightLinked (a, c1)
getClass2: Bidirectional-2 (a) x Class2 (c2) Class1pre:
isLeftLinked (a, c2)
remove: Bidirectional-2 (a) x Class1 (c1) x Class2 (c2) Bidirec374
Appendix B
tional-2
pre: isRelated (a, c1, c2)
isRelated: Bidirectional-2 x Class1 (c1) x Class2 (c2) Boolean
AXIOMS a: Bidirectional-2; c1, cc1: Class1; c2, cc2: Class2; t:
TypeName
name (create (t)) = t
name (add (a, c1, c2)) = name (a)
isEmpty (create (t)) = True
isEmpty (addLink (a, c1, c2)) = False
frozen (a) = <True or False>
changeable (a) = <True or False>
addOnly (a) = <True or False>
get_role1 (a) = <role name>
get_role2 (a) = <role name>
getMult1 (a) = <multiplicity>
getMult2 (a) = <multiplicity>
getVisibility1 (a) = <visibility>
getVisibility2 (a) = <visibility>
isRelated (create (t), c1, c2) = False
isRelated(addLink(a, c1, c2), cc1, cc2) =
(c1 = cc1 and c2 = cc2) or isRelated(a, cc1, cc2)
isRightLinked (create (t), c1) = False
isRightLinked (addLink (a, c1, c2), cc1) =
if c1 = cc1 then True else isRightLinked (a, cc1)
isLeftLinked (create (t), c2) = False
isLeftLinked (addLink (a, c1, c2), cc2) =
if c2 = cc2 then True else isLeftLinked (a, cc2)
rightCardinality (create (t), c1) = 0
rightCardinality(addLink (a, c1, c2), cc1) =
if c = cc1 then 1 + rightCardinality (a, cc1) else rightCardinality
(a, cc1)
leftCardinality (create (t), c2) = 0
leftCardinality(addLink (a, c1, c2), cc2) =
if c2 = cc2 then 1 else leftCardinality (a, cc2)
getClass2 (addLink (a, c1, c2), cc1) =
if c1 = cc1 then add (getClass2 (a, cc1), c2) else getClass2 (a,
cc1)
getClass1 (addLink (a, c1, c2), cc2) = if c2 = cc2 then c1 else
getClass1(a, cc2)
remove (addLink (a, c1, c2), cc1, cc2) =
if (c1 = cc1 and c2 = cc2) then a else remove(a, cc1, cc2)
isRelated (create (t), c1, c2) = False
isRelated(addLink(a, c1, c2), cc1, cc2) =
(c1= cc1 and c2 = cc2) or isRelated(a, cc1, cc2)
END-RELATION
375
Appendix B
4. 17. Bidirectional/ * to *
RELATION SCHEME Bidirectional-3
IMPORTS Collection-C1:Collection [Class1], Collection-C2: Collection
[Class2]
IS-SUBTYPE-OF BinaryAssociation
GENERATED-BY create, addLink
EFFECTIVE
name, frozen, changeable, addOnly, get_role1, get_role2, getMult1,
getMult2, getVisibility1, getVisibility2
create: Typename Bidirectional-3
addLink: Bidirectional-3 (b) x Class1(c1) x Class2 (c2) Bidirectional-3
pre: not isRelated (a, c1, c2)
isEmpty: Bidirectional-3 Boolean
isRightLinked: Bidirectional-3 x Class1 Boolean
isLeftLinked: Bidirectional-3 x Class2 Boolean
rightCardinality: Bidirectional-3 x Class1 Nat
leftCardinality: Bidirectional-3 x Class2 Nat
getClass2: Bidirectional-3 (a) x Class1 (c1) Collection-C2
pre: isRightLinked (a, c1)
getClass1: Bidirectional-3 (a) x Class2 (c2) Collection-C1
pre: isLeftLinked (a, c2)
remove: Bidirectional-3 (a) x Class1 (c1) x Class2 (c2) Bidirectional-3
pre: isRelated (a, c1, c2)
isRelated: Bidirectional-3 x Class1 (c1) x Class2 (c2) Boolean
AXIOMS a: Bidirectional-3; c1,cc1: Class1; c2,cc2:Class2; t:TypeName
name (create (t))= t
name (add (a, c1, c2)) = name (a)
isEmpty (create(t))= True
isEmpty (addLink (a, c1, c2)) = False
frozen (a) = <True or False>
changeable (a) = <True or False>
addOnly (a) = <True or False>
get_role1 (a) = <role name>
get_role2 (a) = <role name>
getMult1(a) = <multiplicity>
getMult2 (a) = <multiplicity>
getVisibility1 (a) = <visibility>
getVisibility2 (a) = <visibility>
isRelated (create (t), c1, c2) = False
isRelated (addLink (a, c1, c2), cc1, cc2) =
376
Appendix B
4. 18. Bidirectional / * to *
RELATION CLASS Bidirectional-4
IMPORTS Collection-C2: Collection [Class2]
Collection-C1:Collection [Class1]
IS-SUBTYPE-OF BinaryAssociation
GENERATED-BY create, addlink
EFFECTIVE
name, create, frozen, changeable, addOnly, get_role1, get_role2,
getMult1, getMult2, getVisibility1, getVisibility2, isRelated
create: Typename Bidirectional-4
addlink: Bidirectional-4 (b) x Class1 (c1) x Class2 (c2) Bidirectional-4
pre: rightCardinality (b, c1) < < m1> and leftCardinality (b, c2) <
<m2>
isEmpty: Bidirectional-4 Boolean
isRightLinked: Bidirectional-4 x Class1 Boolean
isLeftLinked: Bidirectional-4 x Class2 Boolean
rightCardinality: Bidirectional-4 x Class1 Nat
leftCardinality: Bidirectional-4 x Class2 Nat
link1: Bidirectional-4 (a) x Class1 (c1) Collection-C2
377
Appendix B
Appendix B
Appendix B
380
381
Appendix C:
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
Appendix C
context Specification
OCL expressions are written in the context of instances of specific types. The context of an expression
within an UML model can be specified through a context declaration at the beginning of the respective
OCL expression.
In an OCL expression the reserved word self is used to refer to the contextual instance.
invariants
An invariant is a constraint associated with a Classifier that is referred to as a type, and it must be true
for all instances of that type at any time. Invariants are written in a context declaration followed as the
name of the type. The self keyword can be dropped if the context is clear.
Package context
If it is necessary to specify explicitly in which package, due to the package in which the Classifier belongs
is not clear from the environment, we can use the package context. Invariants, preconditions and postcondition constraints can be enclosed between package and endpackage statements as follows:
Package Package::SubPackage
context X
inv: some invariant
context X::operationName ()
pre:some precondition
post:some postcondition
endpackage
Objects and Properties
OCL expressions can refer to Classifiers, e.g. types, classes, interfaces, associations (acting as types)
and data types. All attributes, association-ends, methods and operations without side effects that are
defined on these types can be used in OCL expressions. Operations and methods are defined to be side
effect free if the isQuery attribute of an operation is True. A property can be one of: an attribute, an
association-end, an operation with isQuery being true and a method with isQuery being true
The value of a property of an object is written in an OCL expression by a dot followed by name of
the property.
An operation can be specified in OCL by means of preconditions and postconditions as follows:
Typename:: OperationName (parameter1:Type1,...): ReturnType
pre:_ some expression of self and parameter1
post: Result = _ some function of self and parameter1
self can be used in the expression to refer to the object on which an operation was called and the name
Result is the name of the returned object, if there is any. The names of the parameter (parameter1,...)
can also be used in the expression.
382
Appendix C
The value of a property in a postcondition is the value upon completion of the operation. To refer to
the value of a property at the start of the operation, the property name has a postfix with @ followed
by the keyword pre. Other predefined constraints can appear: changeable, addOnly and frozen in attributes and, ordered, changeable, addOnly, frozen, xor and subset in associations.
383
Appendix C
Sequence.
If the name does not appear in the diagram, is associated by convention the name of the class
association-end.
All types must conform in a valid expression. A type t1 conforms to a type t2 when an instance of t1
can be substituted at each place where an instance of t2 is expected. The basic type conformance rules
are the following ones:
<operation>
OCL Collections are automatically flattened; that is, a collection never contains collections but
contains only simple objects.
OCL defines standard operations on collections such as size, count, includes, includesAll, isEmpty
and notEmpty. Also, OCL provides many operations on the collection types that allow us to iterate over
its elements. They are select, reject, collect, exists, forall and iterate. These operations take each element
and evaluate an expression on them. Following, we describe these operations.
The select and reject operations specify a selection of a special subset from a specific collection. The
select operation gets the subset of all elements of the collection for which the expression evaluates to
True. The syntax of the select operation looks in three different forms:
collection -> select (v: Type |boolean-expression-with-v)
collection -> select (v |boolean-expression-with-v)
collection -> select (boolean-expression)
The first form declares an iterator variable called v. The type of this iterator variable is declared as
Type. The second form is a shorthand notation, in which the type of the iterator variable is omitted. The
third form is the shortest one. It can be used only if an explicit reference to the iterator is not needed in
the expression
The reject operation is identical to the select operation, but with reject we get the subset of all elements of the collection for which the expression evaluates to False.
The syntax of the select operation looks also in three different forms:
collection -> reject (v: Type | boolean-expression-with-v)
collection -> reject (v | boolean-expression-with-v)
collection -> reject (boolean-expression)
384
Appendix C
The collect operation specify a collection which is derived from some other collection, but which
contains different objects from the original collection (i.e, it does not return sub-collections as a select
or reject operation). The syntax of the select operation comes in three different forms:
collection -> collect (v: Type | expression-with-v)
collection -> collect (v | expression-with-v)
collection -> collect (expression)
Because navigation through many objects is very common, OCL provides a shorthand notation for
the collect operation. For any property name that is defined as a property on the objects in the collection,
the following two expressions are equivalents:
collection.propertyname (par1, par2,)
collection -> collect (propertyname (par1, par2,)
The exists operation in OCL allows specifying a Boolean expression, which must hold for at least
one element in the collection. The syntax for the exists operation is as follows:
collection -> exists (v: Type | Boolean-expression-with-v)
collection -> exists (v | Boolean-expression-with-v)
collection -> exists (Boolean-expression)
The iterate operation is the more generic so that operations reject, select, forAll, exists, collect can
be described in terms of the iterate operation. The syntax of the iterate operation is as follows:
collection -> iterate (elem: T; acc: T = <expression> |
with-elem-and-acc)
expression-
The variable elem is an iterator; the variable acc is an accumulator. acc gets an initial value <expression>. The iterates operation iterates over the elements of the collection and the expression-with-elemand-acc is evaluated and its value is assigned to acc. The value of acc is built up during the iteration
of the collection.
The result of the iterate operation can be calculated as is shown in the following pseudocode:
iterate (elem: T; acc: T2 = value)
{ acc = value;
for (Enumeration e = collection.elements (); e.hasMoreElements ();)
{
elem= e.nextElement ();
acc = <expression-with-elem-acc>
}
return acc;
}
385
Appendix C
OCL
NEREUS
R1
v (variable)
v (variable)
R2
R3
R4
R5
R6
v. operationName (parameters)
operationName (TranslateNEREUS (v),TranslateNEREUS (parameters))
R7
self.operationName (parameters)
operationName (c, TranslateNEREUS (parameters))
with [ c| ->self]
R8
R9
R10
v.attributeName
attributeName (v)
R11
context AssociationName
object.roleName
AXIOMS a: AssociationName
get_roleName (a, object)
with [a->Assoc]
R12
expression.operationName
operationName (TranslateNereus (expression))
R13
R14
unaryOperator expression
TranslateNereus (unaryOperator) TranslateNereus (expression)
R15
386
Appendix C
R16
R17
LET
OPERATIONS
f: Element -> Boolean
AXIOMS v: Element
f (v)= Translate NEREUS (boolean-expr-with-v)
IN
operationName (collection, f)
END-LET
---------------------------------------------------------operationName (collection, f)
WHERE
OPERATIONS
f: Element -> Boolean
AXIOMS v: Element
f (v)= Translate NEREUS (boolean-expr-with-v)
END-WHERE
Shorthand notation
operationName (v) (collection, [f (v)])
R18
387
Appendix C
R19
R20
R21
388
Appendix C
R22
R23
389
Appendix C
R24
R25
390
Appendix C
R26
R27
R28
R29
391
Appendix C
R30
R31
R32
R33
R34
392
Appendix C
R35
R36
R37
393
Appendix C
R38
R39
R40
R41
394
Appendix C
R42
R43
R44
R45
R46
R47
R48
R49
R50
Set {}
createSet
OrderedSet {}
createOrderedSet
Sequence {}
createSequence
Bag {}
createBag
Set { e1,e2,...,ei}
Including (including ( (including (createSet, ei),, e2), e1))
OrderedSet {e1,e2,...,ei}
Including (including ((including (createOrderedSet, ei), ,e2),e1))
Sequence {e1,e2,...,ei}
Including (including ((including (createSequence, ei),, e2), e1))
Bag {e1,e2,...,ei}
Including (including ((including (createBag, ei),, e2), e1))
R51
Packagename::rolename
Packagename::rolename
R52
395
396
Appendix D:
Appendix D describes three metamodels for the Observer pattern: a PSM metamodel based on the
Eiffel platform, a PSM metamodel based on a Java platform and a ISM metamodel based on the Java
platform.
DOI: 10.4018/978-1-61520-649-0.ch018
Copyright 2010, IGI Global. Copying or distributing in print or electronic forms without written permission of IGI Global is prohibited.
Appendix D
Associations
association: ObserverSubject [1] It denotes the association of which this end-association is member. It redefines Property::association.
participant: EffectiveObserver [1] It denotes the class that participates in the association.
Constraints
[1] It has a multiplicity n1..n2 (n1>= 0 and n2>=1) self.lower >= 0 and self.upper >= 1
397
Appendix D
AssocEndEffectiveSubject
Description
It connects an association ObserverSubject, of which is member, with a class EffectiveSubject.
Generalizations
Associations
association: ObserverSubject [1] It denotes the association of which the association-end is member. It redefines Property::association.
participant: EffectiveSubject [1] It denotes the class that participates in the association.
Constraints
[1] It has a multiplicity n1..n2 (n1>= 0 and n2>=1) self.lower >= 0 and self.upper >=1
[2] It must be navigable self.isNavigable()
Additional operations
[1] isNavigable denotes whether the association-end is navigable. The association-end is member of a
binary association then, to be navigable, it must be own part of a class. isNavigable(): Boolean isNavigable() = not self.class -> isEmpty()
AssocEndObserver
Description
It connects an association SubjectObserver, of which is member, with a class Observer.
Generalizations
Associations
association: SubjectObserver [1] It denotes the association of which this association-end is member. It redefines Property::association.
participant: Observer [1] It denotes the class that participates in the association.
Constraints
[1] It has a multiplicity n1..n2 (n1>= 0 and n2>=1) self.lower >= 0 and self.upper >= 1
[2] It must be navigable. self.isNavigable()
398
Appendix D
AssocEndSubject
Description
It connects an association SubjectObserver, of which is member, with a class Subject.
Generalizations
Associations
association: SubjectObserver[1] It denotes the association of which this association-end is member. It redefines Property::association.
participant: Subject [1] It denotes the class that participates in the association.
Constraints
[1] It has a multiplicity n1..n2 (n1>= 0 and n2>=1). self.lower >= 0 and self.upper >=1
Attach
Description
It defines a routine that is declared by Subject.
Generalizations
Associations
subject: Subject [1] It denotes the class that declares this routine. It redefines Routine::class.
Constraints
[1] This routine changes the state of the subject. not self.isQuery
[2] This routine has a non-empty set of parameters being one of them an input parameter (direction
= #in) whose type is Observer. self.ownedParameter -> notEmpty () and self.ownedParameter ->
select (par | par.direction = #in and par.type = oclIsKindOf (Observer)) -> size () = 1
[3] Its visibility must be public. self.visibility = #public
399
Appendix D
Detach
Description
It defines a routine that is declared by Subject.
Generalizations
Associations
subject: Subject [1] It denotes the class that is declared by this routine. It redefines
Routine::class.
Constraints
[1] This routine changes the state of the subject. not self.isQuery
[2] It has a non-empty set of parameters being one of them an input parameter whose type is Observer. self.
ownedParameter -> notEmpty () and self.ownedParameter -> select (par | par.direction = #in
and par.type = oclIsKindOf (Observer)) -> size () = 1
[3] Its visibility must be public. self.visibility = #public
EffectiveObserver
Description
This metaclass specifies the features that a class with the behavior of an effective observer must have
in the model of the pattern Observer.
Generalizations
Associations
Constraints
[1] Instances of effective observers should not be a deferred class. not self.isDeferred
400
Appendix D
EffectiveSubject
Description
This metaclass specifies the features that must have a class taking the role of effective subject in the
model of the Observer pattern.
Generalizations
Associations
assocEndEffectiveSubject:AssocEndEffectiveSubject [1] It denotes the association-end of the association ObserverSubject in which this classifier participates.
getState: GetState [1..*] Every instance of EffectiveSubject must have one or more operation instances of GetState. They can be own or inherited. It is a subset of NameSpace::member.
relationshipSubject:RelationshipSubject [1] It denotes a generalization where EffectiveSubject
takes the role of heir. It is a subset of Classifier::generalization.
setState: SetState [1..*] Every instance of EffectiveSubject must have one or more operation instances of SetState. They can be own or inherited. It is a subset of NameSpace::member.
state: Attribute [1..*] It specifies a non-empty set that contains all attributes of EffectiveSubject.
They can be own or inherited. It is a subset of NameSpace::member.
Constraints
[1] Instances of effective subjects should not be a deferred class. not self.isDeferred
GetState
Description
It defines a routine member of EffectiveSubject. It specifies a service that can be required from another
object.
Generalizations
Associations
No additional associations.
Constraints
[1] It is not a deferred routine and does not change the state of the subject not self.isDeferred and self.
isQuery
401
Appendix D
[2] The state should return to the subject, therefore within the set of arguments must have at least one
parameter whose address is out or return. self.ownedParameter -> notEmpty () and self.ownedParameter -> select (par | par.direction = #return or par.direction = #out) -> size () >= 1
[3] Its visibility must be public. self.visibility = #public
Notify
Description
It defines a routine that is declared by Subject.
Generalizations
Associations
Subject: Subject [1] It denotes the class that is declared by this routine. It redefines
Routine::class.
Constraints
[1] This routine does not change the subject state. self.isQuery
[2] Its visibility must be public. self.visibility = #public
Observer
Description
This metaclass specifies the features that must have every class taking the role of observer in the model
of the Observer pattern in the Eiffel platform.
Generalizations
Associations
Constraints
No additional constraints.
402
Appendix D
ObserverSubject
Description
This metaclass specifies a binary association between instances of EffectiveObserver and EffectiveSubject.
Generalizations
Associations
Constraints
[1] It has two association-ends. self.memberEnd -> size () =2
RelationshipObserver
Description
This class specifies the inheritance relation (Generalization) between an observer (Observer) and an
effective observer (EffectiveObserver) in the model of the Observer pattern.
Generalizations
Associations
heir: EffectiveObserver [1] It denotes the element that takes the role of heir in the relation. It redefines Generalization::specific.
parent: Observer [1] It denotes the element that takes the role of parent in the relation. It redefines
Generalization::general.
Constraints
No additional constraints.
403
Appendix D
RelationshipSubject
Description
This metaclass specifies an inheritance relation (Generalization) between a subject (Subject) and an
effective subject (EffectiveSubject) in the model of the Observer pattern.
Generalizations
Associations
heir: EffectiveSubject [1] It denotes the element that takes the role of heir in the relation. It redefines Generalization::specific.
parent: Subject [1] It denotes the element that takes the role of parent in the relation. It redefines
Generalization::general.
Constraints
No additional constraints.
SetState
Descriptions
It defines a routine member of EffectiveSubject. It specifies a service that can be required from another
object.
Generalizations
Associations
No additional associations.
Constraints
[1] It is not a deferred routine and modifies the state of the subset. not self.isDeferred and not self.
isQuery
[2] The set of arguments is non-empty and one of them must be an input parameter. self.ownedParameter -> notEmpty () and self.ownedParameter ->select (par | par.direction= #in) -> size () >=1
[3] Its visibility must be public. self.visibility = #public
404
Appendix D
Subject
Description
This metaclass specifies the features that must have an Eiffel class taking the role of subject in the model
of the Observer pattern in the Eiffel platform.
Generalizations
Associations
Constraints
No additional constraints.
SubjectObserver
Description
This metaclass specifies a binary association between the instances Subject and Observer.
Generalizations
Associations
Constraints
[1] It has two association-ends. self.memberEnd -> size () =2
405
Appendix D
Update
Description
It defines the routine that is declared by the Observer specifying the required services by another object.
Generalizations
Associations
observer: Observer [1] It denotes the class that declares this operation. It is a subset of
Routine::ownedRoutine.
Constraints
[1] It is a routine that does not change the observer state. self.isQuery
[2] Its visibility must be public. self.visibility = #public
Associations
406
association: ObserverSubject [1] It denotes the association of which this association-end is member. It redefines Property::association
participant: ConcreteObserver [1] It denotes the classifier that participates in the association.
Appendix D
Constraints
[1] It has a multiplicity n1..n2 (n1 >= 0 and n2 >= 1). self.lower >= 0 and self.upper > 0
AssocEndConcreteSubject
Description
This association-end connects an association ObserverSubject, of which is member, with a class ConcreteSubject.
407
Appendix D
408
Appendix D
Figure 5. Java PSM observer metamodel: Concrete subject: Attributes and operations
Generalizations
Associations
association: ObserverSubject [1] It denotes the association of which this association-end is member. It redefines Property::association.
participant: Concretesubject [1] It denotes the classifier that participates in the association.
Constraints
[1] It has a multiplicity n1..n2 (n1 >= 0 and n2 >= 1). self.lower >= 0 and self.upper > 0
[2] It is navigable. self.isNavigable ()
Additional operations
[3] The observer operation isNavigable determines whether this association-end is navigable. Due to
it is member of a binary association, to be navigable must be an own association-end of a class. isNavigable(): Boolean isNavigable() = not self.class -> isEmpty ()
AssocEndObserver
Description
It connects an association SubjectObserver, of which is member, with a class Observer.
409
Appendix D
Generalizations
Associations
association: SubjectObserver [1] It denotes the association of which this association-end is member. It redefines Property::association.
participant: Observer [1] It denotes the classifier that participates in the association.
Constraints
[1] It has a multiplicity n1..n2 (n1 >= 0 and n2 >=1). self.lower >= 0 and self.upper > 0
[2] It must be navigable self.isNavigable ()
AssocEndSubject
Description
It connects an association SubjectObserver, of which is member, with a class Subject.
Generalizations
Associations
association: SubjectObserver [1] It denotes the association of which this association-end is member. It redefines Property::association.
participant: Subject [1] It denotes the classifier that participates in the association.
Constraints
[1] It has a multiplicity n1..n2 (n1 >= 0 and n2 >= 1). self.lower >= 0 and self.upper > 0
Attach
Description
It defines a method that is declared by a subject.
Generalizations
410
Appendix D
Associations
classSubject: ClassSubject [0..1] It denotes the class declaring this method. It redefines
JavaOperation::class.
interfaceSubject: InterfaceSubject [0..1] It denotes the interface declaring this method. It redefines Method::interface.
Constraints
[1] This method changes the subject state. not self.isQuery
[2] This method has a non-empty set of parameters, being one of them an input parameter whose type
is Observer. self.ownedParameter -> notEmpty () and self. ownedParameter -> select (param |
param.direction= #in and param.type = oclIsKindOf(Observer)) -> size () = 1
[3] Its visibility must be public. self.visibility = #public
ClassObserver
Description
A metaclass ClassObserver specifies the features that must have a Java class taking the role of observer
in the model of the Observer pattern.
Generalizations
Associations
update: Update [1..*] Every instance of ClassObserver must have at least a method instance of
Update. It is a subset of JavaClass::javaOperation.
Constraints
No additional constraints.
ClassSubject
Description
This metaclass specifies the features that must have a Java class taking the role of subject in the model
of the pattern Observer.
Generalizations
411
Appendix D
Associations
attach: Attach [1..*] Every instance of ClassSubject has at least a method instance of Attach. It is
a subset of JavaClass:: javaOperation.
detach: Detach [1..*] Every instance of ClassSubject has at least a method instance of Detach. It
is a subset of JavaClass:: javaOperation.
notify: Notify[1..*] Every instance of ClassSubject has at least a method instance of Notify. It is a
subset of JavaClass:: javaOperation.
Constraints
No additional constraints.
ConcreteObserver
Description
This metaclass specifies the features that must have a Java class with the behavior of a concrete observer
in the model of the pattern Observer.
Generalizations
Associations
Constraints
[1] An instance of a concrete observer can not be an abstract class. not self.isAbstract
[2] If an instance of a concrete observer participates in an interface realization, then it must be a
BehavioredClassifier. self.interfaceRealizationObserver -> notEmpty () implies self.oclIsKindOf
(BehavioredClassifier))
ConcreteSubject
Description
This metaclass specifies the features that must have a class taking the role of subject in the model of
the Observer pattern.
412
Appendix D
Generalizations
Associations
assocEndConcreteSubject:AssocEndConcreteSubject [1] It denotes the association-end of the association ObserverSubject in which this classifier participates.
generalizationSubject:GeneralizationSubject [0..1] It denotes a generalization where
ConcreteSubject takes the role of child (specific). It redefines Classifier::generalization.
getState: GetState [1..*] Every instance of ConcreteSubject must have one or more method instances of GetState. They may be own or inherited. It is a subset of NameSpace::member.
interfaceRealizationSubject:InterfaceRealizationSubject [0..1] It denotes an interface realization
where ConcreteSubject takes the role of the classifier implementing the contract (implementingClassifier). It is a subset of BehavioredClassifier::interfaceRealization.
setState: GetState [1..*] Every instance of ConcreteSubject must have one or more method instances of SetState. They may be own or inherited. It is a subset of NameSpace::member.
state: Field [1..*] It specifies a non-empty set of all attributes of ConcreteSubject. They may be
own or inherited. It is a subset of NameSpace::member.
Constraints
[1] An instance of the concrete subject can not be an abstract class. not self.isAbstract
[2] If an instance of a concrete subject participates in an interface realization, then it must be a
BehavioredClassifier. self.interfaceRealizationSubject -> notEmpty () implies self.oclIsKindOf
(BehavioredClassifier))
Detach
Description
It defines a method that is declared by a subject.
Generalizaciones
Associations
classSubject: ClassSubject [0..1] It denotes the class that declares this method. It redefines
JavaOperation::class.
interfaceSubject: InterfaceSubject [0..1] It denotes the interface that declares this method. It redefines Method::interface.
413
Appendix D
Constraints
[1] This method changes the subject state. not self.isQuery
[2] This method has a non-empty set of parameters being one of them an input parameter of type
Observer. self.ownedParameter -> notEmpty () and self.ownedParameter -> select (param | param.
direction= #in and param.type = oclIsKindOf (Observer)) -> size() = 1
[3] Its visibility must be public. self.visibility = #public
GeneralizationObserver
Description
This metaclass specifies a generalization between an observer (ClassObserver) and a concrete observer
(ConcreteObserver) in the model of the pattern Observer.
Generalizations
Associations
classObserver: ClassObserver [1] It denotes the general element of this relation. It redefines
Generalization::general.
concreteObserver: ConcreteObserver [1] It denotes the specific element of this relation. It redefines Generalization::specific.
Constraints
No additional constraints.
GeneralizationSubject
Description
This metaclass specifies a generalization between a subject (ClassSubject) and a concrete subject (ConcreteSubject) in the model of the Observer pattern.
Generalizations
Associations
414
classSubject: ClassSubject [1] It denotes the general element of this relation. It redefines
Generalization::general.
concreteSubject: ConcreteSubject [1] It denotes the specific element of this relation. It redefines
Generalization::specific.
Appendix D
Constraints
No additional restrictions.
GetState
Description
It defines a method that is member of ConcretetSubject. It specifies a service that can be required from
another object.
Generalizations
Associations
No additional associations.
Constraints
[1] It is an observer and concrete method. self.isQuery and not self.isAbstract
[2] Because it has to return the state of the subject, the set of parameters should not be empty and at
least, must have one of them whose direction is out or return. self.ownedParameter -> notEmpty
() and self.ownedParameter ->select (par | par.direction= #return or par.direction = #out) -> size
() >=1
[3] Its visibility must be public. self.visibility = #public
InterfaceObserver
Description
The metaclass InterfaceObserver specifies the features that must have a Java interface taking the role
of abstract observer in the model of the Observer pattern.
Generalizations
Associations
update: Update [1..*] Every instance of InterfaceObserver must have at least one operation instance of Update. It is a subset of JavaInterface::method.
Constraints
No additional constraints.
415
Appendix D
InterfaceSubject
Description
This metaclass specifies the features that must have a Java interface taking the role of abstract subject
in the model of the pattern Observer.
Generalizations
Associations
attach: Attach [1..*] Every instance of InterfaceSubject must have at least a method instance of
Attach. It is a subset of JavaInterface::method.
detach: Detach [1..*] Every instance of InterfaceSubject must have at least a method instance of
Detach. It is a subset of JavaInterface::method.
notify: Notify [1..*] Every instance of InterfaceSubject must have at least a method instance of
Notify. It is a subset of JavaInterface::method.
Constraints
No additional constraints.
InterfaceRealizationObserver
Description
This metaclass specifies an interface realization between an abstract observer (InterfaceObserver) and
a concrete observer (ConcreteObserver) in the model of the pattern Observer.
Generalizations
Associations
concreteObserver: ConcreteObserver [1] It denotes the element implementing the contract in this
relation. It redefines InterfaceRealization::implementingClassifier.
interfaceObserver: InterfaceObserver [1] It denotes the element that defines the contract in this
relation.It redefines InterfaceRealization::contract.
Constraints
No additional constraints.
416
Appendix D
InterfaceRealizationSubject
Description
This metaclass specifies an interface realization between an abstract subject (InterfaceSubject) and a
concrete subject (ConcreteSubject) in the model of the pattern Observer.
Generalizations
Associations
concreteSubject: ConcreteSubject [1] It denotes the element implementing the contract in this
relation. It redefines InterfaceRealization::implementingClassifier.
interfaceSubject: InterfaceSubject [1] It denotes the element that defines the contract in this relation. It redefines InterfaceRealization::contract.
Constraints
No additional constraints.
Notify
Description
It defines a method that is declared by the subject.
Generalizations
Associations
classSubject: ClassSubject [0..1] It denotes the class that declares the method. It redefines
JavaOperation::class.
interfaceSubject: InterfaceSubject [0..1] It denotes the interface that declares this method. It redefines Method::interface.
Constraints
[1] It is a method that changes the subject state. self.isQuery
[2] Its visibility is public. self.visibility = #public
417
Appendix D
Observer
Description
An observer is a specialized classifier that specifies the features of observers in the model of the pattern
Observer. It is an abstract metaclass.
Generalizations
Associations
Constraints
No additional constraints.
ObserverSubject
Description
This metaclass specifies a binary association between two instances of Observer and Subject.
Generalizations
Associations
Constraints
[1] It has two association-ends. self.memberEnd -> size () = 2
SetState
Description
It defines an operation that is member of ConcreteSubject. It specifies a service that can be required
from another object.
418
Appendix D
Generalizaciones
Associations
No additional associations.
Constraints
[1] It is a concrete method that modify the subject state. not self.isAbstract and not self.isQuery
[2] It has a non-empty set of parameters and one of them, at least must be an input parameter. self.
OwnedParameter -> notEmpty () and self.OwnedParameter -> select (param | param.direction =
#in) -> size () >= 1
[3] Its visibility must be public. self.visibility = #public
Subject
Description
This metaclass is a specialized classifier that specifies the features that must have instances taking the
role of subject in the model of the pattern Observer. It is an abstract metaclass.
Generalizations
Associations
Constraints
No additional constraints.
SubjectObserver
Description
This metaclass specifies a binary association between two classifiers: Subject y Observer.
Generalizations
419
Appendix D
Associations
Constraints
[1] It has two association-ends. self.memberEnd -> size () = 2
Update
Description
It defines a method that is declared by an observer. This method specifies a service that can be required
by another object.
Generalizations
Associations
classObserver: ClassObserver [0..1] It denotes the class that declares this operation. It redefines
JavaOperation::class.
interfaceObserver: InterfaceObserver [0..1] It denotes the interface that declares this operation. It
redefines Method::interface.
Constraints
[1] It is a method that does not change the observer state. self.isQuery
[2] Its visibility must be public. self.visibility = #public
420
Appendix D
Generalizations
Associations
Appendix D
422
Appendix D
Figure 9. Java ISM observer metamodel: Concrete subject: Operations and attributes
Constraints
[1] This method changes the state of the instance defining it. not self.isQuery
[2] It has a non-empty set of parameters being one of them an input parameter. self.parameter ->
notEmpty () and self. parameter -> select (param | param.direction = #in and param.type = oclIsKindOf (Observer)) -> size () = 1
[3] Its visibility must be public. self.visibility = #public
423
Appendix D
Attach
Description
It defines a method that is declared by a subject.
Generalizations
Associations
classSubject: ClassSubject [0..1] It denotes the class that declares this method. It redefines
JavaOperation::class.
interfaceSubject: InterfaceSubject [0..1] It denotes the interface that declares this method. It redefines Method::interface.
Constraints
[1] This method changes the state of the subject. not self.isQuery
[2] It has a non-empty set of parameters, one of them is an input parameter of type Observer. self.
parameter -> notEmpty () and self. parameter -> select (param | param.direction = #in and param.
type = oclIsKindOf (Observer)) -> size () = 1
[3] Its visibility must be public. self.visibility = #public
[4] If the subject that declares this routine has a reference to a class SubjectObserverAssociation,
then this routine will delegate this task to this class, by invoking to a routine that is an instance of
AddLink. not self.subject.subjectObserverReference -> isEmpty implies self.invokedRoutine ->
exists (r | r.oclIsTypeOf (AddLink))
ClassObserver
Description
A metaclass ClassObserver specifies the features of a class Java taking the role of observer in the model
of a pattern Observer.
Generalizations
Associations
424
update: Update [1..*] Every instance of ClassObserver must have at least a method instance of
Update. It is a subset of JavaClass::javaOperation.
Appendix D
Constraints
No additional constraints.
ClassSubject
Description
This metaclass specifies the features that must have a Java class taking the role of subject in the model
of the pattern Observer.
Generalizations
Associations
attach: Attach [1..*] Every instance of ClassSubject has at least a method instance of Attach. It is
a subset of JavaClass::javaOperation.
detach: Detach [1..*] Every instance of ClassSubject has at least a method instance of Detach. It
is a subset of JavaClass::javaOperation
notify: Notify [1..*] Every instance of ClassSubject has at least a method instance of Notify. It is
a subset of JavaClass::javaOperation.
observerReference: ObserverReference [0..1] It denotes the attribute that allows the subject to
maintain a reference to its observers. It is a subset of JavaClass::field.
subjectObserverReference:SubjectObserverReference [0..1] It denotes the attribute, which is a reference to a class that maintains the relation subject-observers. It is a subset of JavaClass::field.
Constraints
No additional constraints.
ConcreteObserver
Description
This metaclass specifies the features that must have a Java class with the behavior of a concrete observer
in the model of the pattern Observer.
Generalizations
Associations
425
Appendix D
interfaceRealizationObserver: InterfaceRealizationObserver [0..1] It denotes an interface realization where ConcreteObserver takes the role of the classifier implementing the contract. It is a
subset of BehavioredClassifier::interfaceRealization.
subjectReference: SubjectReference [0..1] It denotes a reference to subjects that are observed by
the observer. It is a subset of JavaClass::field.
Constraints
[1] An instance of a concrete observer can not be an abstract class. not self.isAbstract
[2] If an instance of a concrete observer participates in an interface realization, then it must be a
BehavioredClassifier. self.interfaceRealizationObserver -> notEmpty () implies self.superClass
-> exists (c | c.oclIsTypeOf (BehavioredClassifier))
ConcreteSubject
Description
This metaclass specifies the features that must have a class taking the role of concrete subject in the
model of the pattern Observer.
Generalizations
Associations
Constraints
[1] An instance of a concrete subject can not be an abstract class. not self.isAbstract
426
Appendix D
Detach
Description
It defines a method that is declared by a subject.
Generalizations
Associations
classSubject: ClassSubject [0..1] It denotes the class that declares this method. It redefines
JavaOperation::class.
interfaceSubject: InterfaceSubject [0..1] It denotes the interface that declares this method. It redefines Method::interface.
Constraints
[1] This method changes the subject state. not self.isQuery
[2] It has a non-empty set of parameters being one of them an input parameter whose type is Observer. self.
parameter -> notEmpty () and self.parameter ->select (param | param.direction = #in and param.
type = oclIsKindOf(Observer)) -> size () = 1
[3] Its visibility must be public. self.visibility = #public
[4] If the subject that declares this routine has a reference to a SubjectObserverAssociation class, this
routine will delegate its task to this class, by invoking to a routine instance of RemoveLink. not
self.subject.subjectObserverReference -> isEmpty () implies self.invokedRoutine->exists (r |
r.oclIsTypeOf (RemoveLink))
427
Appendix D
GeneralizationObserver
Description
This metaclass specifies a generalization between an abstract observer (ClassObserver) and a concrete
observer (ConcreteObserver) in the model of the pattern Observer.
Generalizations
Associations
classObserver: ClassObserver [1] It denotes the general element of this relation. It redefines
Generalization::general.
concreteObserver: ConcreteObserver [1] It denotes the specific element of this relation. It redefines Generalization::specific.
Constraints
No additional constraints.
GeneralizationSubject
Description
This metaclass specifies a generalization between an abstract subject (ClassSubject) and a concrete
subject (ConcreteSubject) in the model of the pattern Observer.
Generalizations
Associations
Constraints
No additional constraints.
428
Appendix D
GetState
Description
This metaclass specifies a generalization between an abstract subject (ClassSubject) and a concrete
subject (ConcreteSubject) in the model of the pattern Observer.
Generalizations
Associations
No additional associations.
Constraints
[1] It is an observer and concrete method. self.isQuery and not self.isAbstract
[2] As it must return the subject state, the set of parameters must not be empty, and at least, one of the
parameters must have a direction equal to out or return. self.parameter -> notEmpty () and self.
parameter -> select (par | par.direction = #return or par.direction = #out) -> size () >=1
[3] Its visibility must be public. self.visibility = #public
InterfaceObserver
Description
An InterfaceObserver specifies the features that must have a Java interface taking the role of abstract
observer in the model of the pattern Observer.
Generalizations
Associations
update: Update [1..*] Every instance of InterfaceObserver has at least an operation instance of
Update. It is a subset of JavaInterface::method.
Constraints
No additional constraints.
InterfaceSubject
Description
This metaclass specifies the features that must have a Java interface taking the role of abstract subject
in the model of a pattern Observer.
429
Appendix D
Generalizations
Associations
attach: Attach [1..*] Every instance of InterfaceSubject has at least a method instance of Attach. It
is a subset of JavaInterface::method.
detach: Detach [1..*] Every instance of InterfaceSubject has at least a method instance of Detach.
It is a subset of JavaInterface::method.
notify: Notify[1..*] Every instance of InterfaceSubject has at least a method instance of Notify. It
is a subset of JavaInterface::method.
Constraints
No additional constraints.
InterfaceRealizationObserver
Description
This metaclass specifies an interface realization between an abstract observer (InterfaceObserver) and
a concrete observer (ConcreteObserver) in the model of the pattern Observer.
Generalizations
Associations
concreteObserver: ConcreteObserver [1] It denotes the element that implements the contract in
this relation. It redefines InterfaceRealization::implementingClassifier.
interfaceObserver: InterfaceObserver [1] It denotes the element that defines the contract in this
relation. It redefines InterfaceRealization::contract.
Constraints
No additional constraints.
InterfaceRealizationSubject
Descriptions
This metaclass specifies an interface realization between an abstract subject (InterfaceSubject) and a
concrete subject (ConcreteSubject) in the model of the pattern Observer.
430
Appendix D
Generalizations
Associations
concreteSubject: ConcreteSubject [1] It denotes the element that implements the contract in this
relation. It redefines InterfaceRealization::implementingClassifier.
interfaceSubject: InterfaceSubject [1] It denotes the element that defines the contract in this relation. It redefines InterfaceRealization::contract.
Constraints
No additional constraints.
Notify
Description
It defines a method that is declared by a subject.
Generalizations
Constraints
[1] It is a method that does not change the subject state. self.isQuery
[2] Its visibility must be public. self.visibility = #public
[3] If the subject that declares this routine has a reference to a SubjectObserverAssociation class, this
routine will delegate its task to this class by invoking this routine instance of NotifyObserver. not
self.subject.subjectObserverReference -> isEmpty implies self.invokedRoutine -> exists (r |
r.oclIsTypeOf(NotifyObserver))
NotifyObservers
Description
It defines a method that is declared by an instance of SubjectObserverAssociation.
Generalizations
431
Appendix D
Associations
Constraints
[1] This is a method that does not change the state of the instance that defines it. self.isQuery
[2] Its visibility must be public. self.visibility = #public
Observer
Description
An observer is a specialized classifier that specifies a classifier whose role is observer in the model of
the pattern Observer. It is an abstract metaclass.
Generalizations
Associations
No additional associations.
Constraints
No additional constraints.
ObserverReference
Description
This field represents a reference to observers of a subject.
Generalizations
Associations
subject: Subject [1] It denotes the class that declares this field. It redefines Field::class.
Constraints
[1] The type of this field must correspond to some of the collections of the Java library. self.type.
oclIsKindOf (JavaCollection) and self.type.parameter -> size () = 1 and self.type.parameter.
ownedParameteredElement.oclIsTypeOf (Observer)
432
Appendix D
[2] Its visibility must be private or protected. self.visibility = #private or self.visibility = #protected
RemoveLink
Description
It defines a method that is declared by an instance of SubjectObserverAssociation.
Generalizations
Associations
Constraints
[1] This method changes the state of instances defining it. not self.isQuery
[2] It has a non-empty set of parameters being one of them an input parameter whose type is observer. self.parameter -> notEmpty() and self.parameter -> select (param | param.direction = #in
and param.type = oclIsKindOf (Observer)) -> size () = 1
[3] Its visibility must be public. self.visibility = #public
SetState
Description
It defines an operation member of ConcreteSubject. It specifies a service that can be required from
another object.
Generalizations
Associations
No additional associations.
Constraints
[1] This is a method that is concrete and modifies the state of the subject. not self.isAbstract and not
self.isQuery
[2] It has a non-empty set of parameters being at least one of them an input parameter. self.parameter
-> notEmpty () and self.parameter ->select (param | param.direction = #in) -> size () >= 1
[3] Its visibility must be public. self.visibility = #public
433
Appendix D
Subject
Description
This metaclass specifies a specialized classifier that takes the role of subject in the model of the pattern
Observer. It is an abstract metaclass.
Generalizations
Associations
No additional associations.
Constraints
No additional constraints.
SubjectObserverAssociation
Description
This metaclass specifies the features of the class that maintains the relation between a subject and its
observers.
Generalizations
Associations
Constraints
No additional constraints.
SubjectObserverMapping
Description
This metaclass specifies the class attribute SubjectObserverAssociation, that maintains the mapping
between a subject and its observers.
434
Appendix D
Generalizations
Associations
Constraints
[1] Its visibility must be private or protected. self.visibility = #private or self.visibility = #protected
SubjectObserverReference
Description
This attribute is a reference to a class SubjectObserverAssociation, which maintain the relation between
a subject and its observers.
Generalizations
Associations
subject: Subject [1] It denotes the class that declares this attribute. It redefines Attribute:: class.
type: SubjectObserverAssociation [1] It refers to the type of this attribute. It redefines
Attribute::type.
Constraints
No additional constraints.
Update
Description
It defines a method that is declared by an observer which specifies a service that is required by another
object.
Generalizations
435
Appendix D
Associations
classObserver: ClassObserver [0..1] It denotes the class that declares this operation. It redefines
JavaOperation::class.
interfaceObserver: InterfaceObserver [0..1] It denotes the interface that declares this operation. It
redefines Method::interface.
Constraints
[1] This is a method that does not change the state of the observer. self.isQuery
[2] Its visibility must be public. self.visibility = #public
436
437
Liliana Favre is a full professor of Computer Science at Universidad Nacional del Centro de la
Provincia de Buenos Aires in Argentina. She is also a researcher of CIC (Comisin de Investigaciones
Cientficas de la Provincia de Buenos Aires). Her current research interests are focused on model driven
development, model driven architecture and formal approaches, mainly on the integration of algebraic
techniques with MDA-based processes. She has been involved in several national research projects
about formal methods and software engineering methodologies. Currently she is research leader of the
Software Technology Group at Universidad Nacional del Centro de la Provincia de Buenos Aires. She
has published several book chapters, journal articles and conference papers. She has acted as editor of
the book UML and the Unified Process.
Copyright 2010, IGI Global, distributing in print or electronic forms without written permission of IGI Global is prohibited.
438
Index
B
Bag type 84, 95
basic specification 98, 99
Boolean basic type 84, 87, 88, 89, 91, 92, 93,
94, 95, 96
Boolean expressions 111
BOX_ scheme 80, 82, 90
business rules 1, 2, 31
byte code 1
Copyright 2010, IGI Global, distributing in print or electronic forms without written permission of IGI Global is prohibited.
Index
D
data abstraction 102
data encapsulation 102
data flow graph 201, 208, 209, 210, 211
data mining 201
data reverse technologies 201
data types 35, 36
data warehouse 201
DEFERRED clause 107
design 1, 2, 3, 5, 6, 10, 13, 15, 17, 22, 27, 30,
31
design patterns 1, 6, 115, 116, 117, 119, 156
design pattern techniques, evolution of 116
design recovery 2
design views 1
diagram interchange specifications 8
domain specific language (DSL) 8, 11, 31, 35,
204, 232, 233
dynamic analysis 200, 201, 204, 205, 206, 207,
208, 211, 212, 213, 214, 215
E
Eclipse generative modeling tools (EclipseGMT) 204
Eclipse Modeling framework 51
Eclipse open source framework 204, 227
EffectiveObserver abstract class 138
F
first-order logic 98
formal specifications 11, 159, 160, 199, 203,
204, 205
forward engineering 2, 3, 6, 7, 9, 10, 16, 17,
49, 158, 159, 243, 245, 249, 250, 252
free specifications 98, 100
Fujaba Tool Suite project 204
G
generated specifications 98, 100
Graph Transformation platform 204
H
heuristics 107, 112
Hide operator 100
high-level architecture 201
high-level views 1
I
implementation component model (ICM) 262
implementation level 109
implementation pieces 115
implementation specific abstraction levels 158
implementation specific model (ISM) 7, 8, 9,
11, 16, 18, 26, 34, 39, 41, 43, 115, 116,
117, 118, 119, 120, 140, 141, 142, 143,
144, 159, 160, 183, 204, 205, 206, 218,
219, 220, 221, 222, 225, 226, 232, 233
439
Index
J
JavaClass 218, 219, 220, 221, 222
Java-ISM Observer Metamodel 420
Java platform 119, 120, 136, 137, 138, 139,
140, 141, 142, 143, 144, 157
Java program 211, 214
Java-PSM Observer Metamodel 406
Java source code 159
Java statements 209, 210
L
Leaf pattern 162, 163, 165, 166, 167, 168, 169,
171, 172, 173, 175, 183, 184, 187, 188,
189
legacy code 1, 5
legacy systems 1, 2, 10, 17
loose specifications 98, 100
M
MDA-based CASE tools 115
MDA-based object oriented reverse engineering 199
MDA-based processes 49
MDA-based software development processes
49
MDA-based tools 273
MDA reverse engineering 231, 232
MDA technical issues 115
megamodels 115, 116, 117, 118, 119
membership equational logic (MEL) 51
metaclasses 116, 120, 121, 122, 127, 128, 129,
130, 132, 133, 134, 135, 137, 139, 142,
162, 163, 168, 170, 173
440
Index
N
NEREUS 258, 259
NEREUS classes 107
NEREUS constructions 107
NEREUS metamodeling language 11, 49, 52,
53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 67,
69, 72, 75, 80, 81, 83, 84, 85, 86, 87, 88,
89, 90, 92, 95, 97, 98, 99, 100, 102, 107,
108, 112, 113, 116, 150, 154, 158, 160,
185, 189, 190, 191, 196, 205, 224, 225,
233, 332, 333, 334, 336, 337, 338, 339,
350, 353, 355
NEREUS specifications 107
O
object constraint language (OCL) 6, 8, 10, 14,
16, 18, 19, 25, 28, 29, 33, 35, 37, 38, 45,
47, 158, 174, 178, 183, 184, 190, 193,
196, 199, 203, 204, 205, 207, 213, 214,
219, 221, 222, 225, 228, 232, 233, 234,
242, 243, 244, 245, 247, 248, 250, 251,
252, 254, 332, 333, 335, 336, 337, 338,
344, 345, 352, 354, 355, 381, 382, 383,
384, 385, 386
object diagram 199, 202, 204, 208
object flow graph 5
Object Management Group (OMG) 6, 8, 10,
11, 14, 15, 16, 17, 21, 24, 25, 28, 30, 31,
32, 33, 34, 38, 47, 201, 204, 228, 229,
238, 253
object-oriented code 107, 199, 200, 204, 206,
208, 213, 227
object-oriented languages 5, 107, 108
object-oriented program model 207, 214
object-oriented programs 212
Observer abstract class 116, 118, 120, 121,
122, 123, 124, 125, 126, 127, 128, 129,
130, 131, 132, 133, 134, 135, 136, 137,
138, 139, 140, 141, 142, 143, 144, 145,
146, 148, 149, 150, 152, 154, 155
P
package diagram 199, 201, 202, 204, 208
PackageObserver Metamodel 150
Packages 35, 37
packages diagrams 80
parameters 117, 127, 130, 135, 144, 145, 147,
148, 149, 150
partial functions 98, 99
Participates associaton 111
pattern solutions 116, 117
perfective model evolution 158
person and meeting (P&M) class diagram 85,
91, 96, 97, 111
platform component description (PDM) 20
platform independent abstraction levels 158
platform independent component model
(PICM) 262
platform independent model (PIM) 6, 8, 9, 10,
11, 16, 18, 19, 20, 46, 47, 115, 116, 117,
118, 119, 120, 121, 122, 137, 139, 144,
146, 147, 148, 149, 150, 154, 155, 158,
159, 160, 161, 183, 190, 199, 200, 203,
204, 205, 206, 232, 233, 235, 253
platform specific abstraction levels 158
platform specific component model (PSCM)
262
platform specific model (PSM) 7, 8, 9, 11, 16,
18, 20, 34, 46, 115, 116, 117, 118, 119,
120, 136, 137, 138, 139, 140, 141, 144,
145, 146, 148, 149, 150, 154, 155, 158,
159, 160, 161, 199, 200, 203, 204, 205,
206, 207, 218, 219, 220, 221, 222, 225,
232, 233, 235, 253, 255
polymorphism 212
postcondition assertions 111, 112
441
Index
Q
query, view, transformation (QVT) metamodel
8, 14, 17, 28, 29, 30, 33, 45, 47, 51, 52,
73, 74, 75, 79, 203, 204, 243, 256
QVT-Core 232
R
rational unified process (RUP) 21, 22, 27
Real basic type 84
realization sub-component 108
reengineering 2, 3, 4, 5, 6, 9, 10
refactoring 158, 159, 160, 161, 162, 163, 169,
170, 174, 182, 183, 184, 185, 189, 190,
191, 192, 193, 194, 196, 197, 244, 245,
247, 251, 252
refactoring techniques 159, 160
refinements 117, 118, 120, 150, 154
Relation language 52, 73, 74
renaming operators 98
requirements 1, 2, 3, 6, 18, 21
restructuring 2
reusability 115
reusable components 115, 117, 119
reusable infrastructure 49
reusable schemes 80
reverse engineering 1, 2, 3, 4, 5, 6, 9, 10, 11,
12, 13, 14, 17, 20, 26, 49, 53, 158, 159,
199, 200, 201, 202, 203, 204, 205, 206,
208, 213, 214, 215, 218, 222, 226, 231,
232, 233, 234, 235, 243, 244, 245, 249,
252
role-based modeling language (RBML) 116
round-trip engineering 49
442
S
sequence diagram 199, 222
Sequence type 84, 91
Set type 84, 93, 94, 95
slicing techniques 4
software artifacts 1, 2, 3, 8, 35, 199, 201
software evolution 236, 237, 238, 239
software language engineering 235
software process engineering 235
software process engineering metamodel
(SPEM) 17, 21, 24, 27, 33
software quality 116
sorts 98, 99
source code 1, 3, 4, 6, 7, 10, 12, 16, 199, 201,
202, 203, 204, 206, 207, 208, 214
source metamodel 160, 161, 162, 163, 180,
181, 182, 183, 185
specification techniques, formal 49, 50, 51, 52,
53, 56, 77, 79
specification techniques, semiformal 49, 50
state diagrams 199, 201, 202, 204, 205, 208,
215, 216, 217, 222
static analysis 4, 5, 10, 12, 200, 202, 204, 205,
206, 207, 208, 211, 212, 213, 214
stereotypes 51
Story Diagrams 204
Story Driven Modeling 204
String basic type 84, 90, 92, 93, 95
structural pattern specification (SPS) 117
structured specifications 98, 99
subclass 161, 163, 165, 166, 168, 169, 171,
173, 174, 183
Subject abstract class 120, 121, 126, 127, 128,
129, 132, 134, 135, 136, 137, 138, 151,
152
SubjectObserverAssociation 143, 144
SubjectObserverMapping 143
SubjectObserverReference 141, 142
subsorts 98, 99
superclass 161, 165, 166, 168, 171, 173, 174,
183
SYNTROPY method 381
system entities lifecycle 199, 204
system functionality 231
system processes 199, 204
Index
T
target metamodel 160, 161, 162, 163, 180, 181
taxonomy of associations 108
traceability 1, 12
transformation processes 80
transformation rules 80, 84, 85, 95, 107
transformation rule system 381, 382, 383, 384,
385, 386, 387, 388, 389, 390, 391, 392,
393, 394, 395
transformations 107, 109, 116, 117, 143, 144,
149, 150, 154, 155, 157
trivial translation 107
trusted components 157,
V
validation 116
verification 116
Z
Z language 50
443