Diplomarbeit

Metamodel Evolution in the Context of a MOF-Based Infrastructure

eingereicht am 30.09.2008 beim Institut für Theoretische Informatik der Universität Karlsruhe (TH)

Dozent: Prof. Dr. P. H. Schmitt Betreuer: Dipl.-Ing. Boris Gruschko, SAP AG

Erik Burger Im Bauernbrunnen 8 74821 Mosbach Matrikelnummer: 1146018 E-Mail: [email protected] Versicherung der selbständigen Erarbeitung Ich versichere hiermit, dass ich die vorliegende Arbeit selbständig verfasst und weder ganz oder in Teilen als Prüfungsleistung vorgelegt und keine anderen als die angegebenen Hilfsmittel benutzt habe. Sämtliche Stellen der Arbeit, die benutzten Werken im Wortlaut oder dem Sinn nach entnommen sind, habe ich durch Quellenangaben kenntlich gemacht. Dies gilt auch für Zeichnungen, Skizzen, bildliche Darstellungen und dergleichen sowie für Quellen aus dem Internet.

Ort, Datum:

Unterschrift:

Zuletzt geändert am 27.9.2008 CONTENTS i

Contents

1 Introduction 1 1.1 ProblemStatement...... 1 1.2 Structure ...... 1

2 Background 2 2.1 Model-Driven Architecture (MDA) ...... 2 2.2 Meta-ObjectFacility(MOF) ...... 2 2.3 JMI ...... 4 2.4 MOIN...... 6

3 Changes in MOF-Based Metamodels 8 3.1 Definition ...... 8 3.2 Prerequisites ...... 8 3.3 Classification ...... 9 3.4 DeterminationofOverallSeverity...... 17 3.5 MOIN-SpecificChanges ...... 19

4 Query Visibility of Changes 21 4.1 Changes Without Effects on Queries and Result Sets ...... 21 4.2 ChangesAffectingtheResultSet ...... 21 4.3 ChangesMakingtheQueryInvalid ...... 22

5 JMI Interfaces 24 5.1 JMIMetamodel...... 24 5.2 JMITransformationMetamodel...... 28 5.3 ChangesinJMIInterfaces ...... 31 5.4 AssignmentofMOFChangestoJMIChanges...... 33

6 Example 38 6.1 Description ...... 38 6.2 SeveritiesregardingM1instances ...... 39 6.3 SeveritiesregardingQueries ...... 39 6.4 Transformation into JMI model instance ...... 39 6.5 SeveritiesregardingJMIinterfaces ...... 40

7 Related Work 44 7.1 MOFrepositories...... 44 7.2 MetamodelEvolution ...... 44

8 Conclusion 46

Bibliography 47

Glossary 49

Appendices

A Change Severities Overview 50 CONTENTS ii

B OCL Constraints 53 B.1 ChangeMetamodelConstraints ...... 53 B.2 SeverityConstraints ...... 55 B.3 JMIMetamodelConstraints...... 59 B.4 HelperFunctions ...... 67 LIST OF FIGURES iii

List of Figures

1 TheMOFabstractionlayers...... 2 2 The MOF metamodel, simplified view (from [Het06]) ...... 3 3 Generated inheritance patterns (from [JMI02]) ...... 5 4 TheMOFchangemetamodel ...... 7 5 Example: Deletion of a class makes M1 data invalid ...... 10 6 Example: Associationcardinality ...... 11 7 Example:Compositioncycle ...... 14 8 Example:Containmentchange ...... 16 9 Example: Deletion of generalization leads to invalid M1 data ...... 16 10 Example: Typechangeonanassociationend ...... 17 11 Example: Changeintypehierarchy...... 18 12 Example: Inversionoftypehierarchy ...... 19 13 Query visibility: Adding generalization ...... 21 14 Query visibility: Deleting generalization ...... 22 15 Query visibility: Deleting generalization with association...... 23 16 TheJMImetamodel ...... 26 17 TheJMIprimitivetypepackage ...... 27 18 TheJMIreflectivepackage ...... 27 19 MOFtoJMItransformationprocess ...... 28 20 Thetransformationmetamodel ...... 32 21 Examplemetamodel ...... 38 22 ChangestepsasChangeMetamodelinstances ...... 38 23 Examplemetamodel,Version1 ...... 41 24 Examplemetamodel,Version2 ...... 42 25 JMI interfaces of example metamodel, Version 2 ...... 43 Abstract The evolution of software systems can produce incompatibilities with existing data and appli- cations. For this reason, changes have to be well-planned, and developers should know the impact of changes on a software system. This also affects the branch of model-driven development, where changes occur as modification of the metamodels that the system is based on. Models that are instantiated from an earlier metamodel version may not be valid instances if the new version of a metamodel. Also, changes in the interface definition may require adaptations to the modeling tools. In this thesis, the impact of meta-model changes is evaluated for the modeling standards Meta Object Facility (MOF) and the interface definition Java Metadata Interface (JMI), based on the Modeling Infrastructure (MOIN) project at SAP, which includes a MOF- based repository and im- plements the JMI standard. For the formalisation of changes to MOF-bases metamodels, a Change Metamodel is introduced to describe the transformation of one version of a metamodel to another by the means of modeling itself. The changes are then classifed by their impact on the compatibility of existing model data and the generated JMI interfaces. The description techniques and change classifications presented in this thesis can be used to implement a mechanism that allows metamodel editors to estimate the impact of metamodel changes with the help of modeling tools that can adapt existing data semi-automatically.

Zusammenfassung Die Weiterentwicklung von Software-Systemen kann zu Inkompatibilitäten mit bestehenden Daten und Anwendungen führen. Daher sollten die dabei vollzogenen Änderungen gründlich geplant werden, und Entwickler sollten sich der Folgen von Änderungen an einem Software-System bewusst sein. Dies betrifft auch modellgetriebene Entwicklung, bei der Änderungen in Form von Modifikationen an den zugrundeliegenden Metamodellen auftreten. Bestehende Modelldaten, die aus einer früheren Version des Metamodells heraus instanziiert wurden, sind nicht zwingend gültige Instanzen einer weiterentwi- ckelten Version. Weiterhin können Änderungen in der Schnittstellen-Spezifikation es erfordern, dass vorhandene Modellierungswerkzeuge angepasst werden. In dieser Arbeit werden die Auswirkungen von Änderungen an Metamodellen für die Model- lierungsstandards Meta Object Facility (MOF) und Java Metadata Interface (JMI) untersucht. Dies geschieht anhand des SAP-Projektes Modeling Infrastructure (MOIN), welches ein MOF-basiertes Metadaten-Repository enthält und den JMI-Standard implementiert. Für die formale Definiton von Änderung an MOF-basierten Metamodellen wird zuerst ein Ände- rungs-Metamodell (Change Metamodel) vorgestellt, mithilfe dessen die Transformation einer Metamo- dell-Version zur nächsten unter Verwendung von Modellierungstechniken beschrieben werden kann. Diese Änderungen werden dann anhand ihrer Auswirkung auf die Kompatibilität zu bestehenden Modelldaten und Schnittstellen klassifiziert. Die Beschreibungstechniken und die Klassifizierung, die in dieser Arbeit vorgestellt werden, können für eine Implementierung genutzt werden, die es Metamodell-Entwicklern erlaubt, die Folgen von Änderungen an Metamodellen für bestehende Daten und Anwendungen einzuschätzen und diese mit halbautomatischer Unterstützung anzupassen. 1 INTRODUCTION 1

1 Introduction

One of the challenges in software development is the handling of evolutionary changes in a software system. If a system evolves, the functionality and the interfaces may be changed in a way that existing applications that are built on top of this system cannot continue working without adaptation to the new circumstances. For this reason, changes to a system have to be well-planned, and the impact on existing data and application must be described so that existing applications can be adapted. In order to keep this effort as small as possible, it is preferable if the effect of changes on existing installations is predictible, so that the modification of a system can be performed with knowledge of the impact it may have. In the field of model-driven development, systems are described by modeling languages such as the Meta Object Facility (MOF). Together with the graphical notation of the Unified Modeling Language (UML), domain-specific metamodels are created that reflect the properties of a certain business domain. These metamodels are afterwards instantiated as actual models by customers for the description of their data.

1.1 Problem Statement Like every kind of software component, metamodels are also subject to evolutionary changes, for example if a new version of the piece of software that includes the metamodel is released. If customers of this software have built models with the previous version, they rely on the availability of migration rules to adapt their model content to the new version. On the side of the software developer, the editor of the metamodel should be aware of the way in which changes to the metamodel layout will affect the compatibility to existing data in terms of metamodel compliance and interface compatibility, so that the tools that the modeling software offers can still be used by customers of the previous versions. This problem does not only affect the relationship of the software vendor to a customer. Since the roles of the metamodel editor and the software engineer who implements the modeling tools can be taken by different persons, the knowledge of the impact of changes to the metamodel is also relevant for the internal software development process. Furthermore, the MOF specification does not offer a standard for the description of evolution of metamodels, so a formalisation for metamodel changes has to be found in order to describe the possible impacts in a structured way.

1.2 Structure In this thesis, the problem of metamodel evolution will be evaluated for an actual implementation of a MOF-based repository within the MOIN project at SAP1. The general problem description is solely based on MOF, but specific problems for the MOIN implementation are also regarded. The structure of this thesis is as follows: Firstly, the technologies that are used in the course of this thesis are introduced and described briefly. For the description of possible changes to MOF-based metamodels, a change metamodel will be introduced, which is itself described by the means of MOF. Furthermore, change severities are defined by which the single metamodel change types will then be classified with respect to their impact on systems with existing model data. Furthermore, the problem of the determination of change severities for sequences of changes is discussed, and OCL constraints are presented for common combinations of metamodel changes. In the next section, the impact on the query infrastructure of MOIN is described. Subsequently, the same is done for the Java interfaces in Section 5, and the results of these investigations are presented in an overview table in Appendix A. This thesis finishes with an example demonstrating metamodel evolution case, references to related works and an outlook at future work based on the results of this work. 1SAP is a trademark or registered trademark of SAP AG in Germany and in several other countries. 2 BACKGROUND 2

2 Background 2.1 Model-Driven Architecture (MDA) The notion Model-Driven Architecture (MDA) denotes a software development approach that was launched by the Object Management Group (OMG) in 2001. It focuses on integration and inter-operability in software development, covering all phases from specification and design through implementation and lifecycle management. Several technologies were standardized by the OMG, such as CORBA, UML, MOF and XMI. The UML standard is a widely adopted modelling language for object-oriented software design, as well as XMI for the interchange of model data. The MOF standard is described below. The MDA approach [MDA03] defines a number of concepts, which are described in brief here: Model A model is the description or specification of a system and its environment. This description can be graphical, in formal or natural language. Model-Driven MDA is a system development approach that makes use of models for understanding, designing, and modificating systems. Architecture The architecture is the specification of the parts and connectors of a system and the rules for the interaction of these parts. Platform A platform contains the technological and engineering details that are not relevant to the functionality of a system. It offers interfaces and specified usage patterns to allow usage of the system without knowledge of the internal technical structure.

2.2 Meta-Object Facility (MOF) The Meta Object Facility specification [MOF02] defines a formal language and framework for the descrip- tion of metamodels. MOF is a standard that was developed by the Object Management Group (OMG). It was created as a language for the description of a metamodel for the Unified Modeling Language (UML). MOF also specifies an Interface Description Language (IDL) for the access and manipulation of metadata. A good introduction into MOF can be found in the introductory chapters of the specification of the Java Metadata Interface (JMI) [JMI02]. The current version of the standard is MOF 2.0; however, the subject of this thesis is based on MOF 1.4.

M3 Layer MOF model

M2 Layer metamodels (e.g. UML metamodel)

M1 Layer models (e.g. UML models) instantiation

M0 Layer actual objects (data)

Figure 1: The MOF abstraction layers 2 BACKGROUND 3

2.2.1 Design When speaking about metadata (which is often described as “data about data”), one could theoretically create an arbitrary number of meta-layers, since every kind of data can be described by a corresponding set of meta-data. (And thus the meta-data itself, and the meta-meta-data etc.) MOF is organized in a four-layered architecture in which the layers represent different levels of abstraction. The four layers are named M0 to M3, with M3 being the highest level. The separation of layers is strict, meaning that elements of a layer can only reference elements of the same layer and can only be instances of the elements in the layer above. The only exception to this rule is the MOF model itself (see below).

M3 Layer The M3 layer contains the MOF metamodel (also called MOF model). The MOF model is used to instantiate metamodels, which are then part of the M2 layer. The MOF model, however, is an instance of itself. This means, for example, that the element Class in the MOF metamodel is its own meta-object. For this reason, MOF can be called a closed metamodelling architecture.

M2 Layer The M2 layer contains metamodels, which are instances of the MOF model. For example, the UML metamodel is part of the M2 layer.

M1 Layer In the M1 layer (also called model layer) describes the format and semantics of data. It contains models. For example, UML models are part of the M1 layer.

M0 Layer The M0 layer or information layer contains the actual objects or instances and thus, the data. For our considerations, the M0 layer is not of interest.

ModelElement

Package Classifier 1 contains * Feature

1 type

* DataType Class Attribute Reference

0..1

references

1 Association 1 2 AssociationEnd

Figure 2: The MOF metamodel, simplified view (from [Het06]) 2 BACKGROUND 4

2.2.2 Internal Structure MOF was originally derived from a subset of UML and shares many common modeling elements with UML: The main elements are called classes, which are connected by associations, which have each two association ends. The instances of associations are called links. For the convenient access of associations, classes can contain references, which like association ends and attributes have a type, which is modeled as the association IsOfType. In the MOF metamodel, the concept of inheritance is called generalization, which is represented by the Generalizes association. Figure 2 shows an excerpt of the MOF model. The self-containedness property of MOF can be seen here: The MOF model is described in itself, using principles like classes, inheritance and associations in a diagram.2 The complete model is too complex to be depicted or described in its entireness here; this is why we chose to include only the simplified view here. For the understanding of the following chapters, and for details of the standard, the MOF specification document [MOF02] should be regarded.

2.2.3 OCL The Object Constraint Language (OCL) is a declarative, strongly typed, side-effect free language that was originally created as a constraint language for UML. In its current version, it can be used with any MOF-compliant metamodel in order to express additional constraints that cannot be expressed by the means of graphical notation. OCL is now part of the MOF 2.0 standard. Its specification can be found in [OCL06].

2.3 JMI In order to access metadata in Java, the Java Metadata Interface (JMI) standard offers an API to discover, retrieve and manipulate metadata elements. The standard is being developed in the Java Community Process as Java Specification Request (JSR) 040; the current version is 1.0 of 2002. The JMI standard is based on MOF 1.4 in its current version; a language binding for MOF 2.0 does not exist yet.

2.3.1 Design As a metadata API, JMI defines the Java representation of models. In Figure 3, an example model can be seen on the left side. The generated Java interfaces for these elements are on the bottom right. JMI offers two ways to access metadata: The reflective interfaces and the generated, tailored interfaces. The reflective operations are defined in the classes whose names start in “Ref” and can be seen on the top right. The generated interfaces inherit from these reflective interfaces. As it can be seen in Figure 3, the classes on the MOF side (C1, C2) each have two representations on the Java side: An instance interface that extends RefObject (C1, C2), and a class proxy interface (C1Class, C2Class) that extends RefClass. This is caused by the fact that unlike package instances or links (which are association instances), class instances have real object identity. While the package objects are merely a collection of the objects that they contain, and association objects contain the collection of links, which have no properties except the information of their existence, class instances have more complex features and are thus represented as Java instances. The class proxy instances are used for the creation of class instances, and they also hold the classifier-scoped3 features of a class. Furthermore, the reflective interface allows the discovery of an element’s features4 and allows a pro- gram to use them without prior knowledge. For example, if a class has a property attr1, then there are generated (tailored) operations to access this property, called getAttr1() and setAttr1(). If it is not known whether an object has this property, it is not possible to use these operations because the Java type check would fail, since getAttr1() is not defined for RefObject. Using the reflective interface, the property could be accessed by refGetValue("attr1"), which would throw an exception at runtime if the property does not exist. Using refMetaObject(), the existence of the property could also be checked before. 2To make the issue even more confusing, UML is the language for the graphical notation of MOF and its metamodels. 3 Equivalent to static in Java 4Like the reflective package in Java 2 BACKGROUND 5

It is also possible to navigate between the model layers using the refMetaObject() operation. In the example of Figure 3, the M2 level is represented on the Java side as the interfaces C1, C2 and so on. If M1 data is created, it is represented as instances of these classes. If refMetaObject() is now invoked on 5 such instances, it returns an instance of MofClass with the attribute name set to C1. The metaobject of this element is an instance of MofClass with the name Class, which is then its own metaobject.

RefBaseObject

P1 P2 RefPackage RefAssociation RefFeatured

RefObject RefClass Package P1

C1

A P1 A C1Class C2Class

C2 C1

P2 C2

MetamodelDefinition InheritanceinGeneratedInterfaces

Figure 3: Generated Java inheritance patterns (from [JMI02])

2.3.2 Special Tags Relevant for JMI packagePrefix For the generated Java classes and packages, it may be necessary to define a prefix for the Java package names. (e.g. java.lang.reflect) Since this prefix is only relevant for the generation of JMI interfaces, it is not used in the names of every element, but instead saved in a tag which is attached to the package in which the elements are contained. methodPrefix The method prefix is similar to the above mentioned package prefix. If a method prefix is specified, the string is applied to all names of generated operations of that package. substituteName Not all names that can be used for model elements can also be used in the Java interfaces because there are certain keywords (like e.g. Class) that cannot be used as an identifier. For this purpose, JMI

5 This Java class represents the MOF model element Class; but since this is a reserved keyword in Java, the name MofClass was chosen as the substitute name for the JMI interface. 2 BACKGROUND 6 specifies a tag with which a substitute name for interface generation can be provided. This is relevant for the impact of metamodel changes on the JMI interfaces, which is described in Subsection 5.3.

2.4 MOIN The Modeling Infrastructure (MOIN) at SAP provides a MOF-based repository and several metadata services that can be used as the base for metamodeling tools. In the MOF specification, the purpose of a metadata repository is seen in “storing the representations of models and a collection of associated tools” [MOF02, section 5.2]. The models that are persisted and managed by the repository represent the M1 layer, while the metamodels that they are based on (M2 layer) are usually fixed. In the case of MOIN, tools can connect via JMI, or they can use the Query Infrastructure using the MOIN Query Language (MQL). An OCL parser and evaluator is also provided that checks metamodel constraints. Metadata can be persisted in the file system as well as on a database. For creation and editing of metamodels, a graphical model editor can be used within the Eclipse-based SAP Netweaver DeveloperStudio.

2.4.1 Special Tags 2.4.1.1 Storage When a link on M1 level is to be persisted, there are three possible ways of storing the information: On either one side of the link or on both sides. In MOIN, there is a special tag that defines the storage of a link. Currently, MOIN uses one-sided storage, meaning that if a link is created between two elements on M1 level, the information on this link is only stored in one of the elements.6 In the metamodel, the Storage tag is attached to the AssociationEnd on the side of the association where it is to be stored. The metamodel author should decide about link storage for every Association created. If no storage tag is present, MOIN sets it automatically, depending mainly on the existence of references in the classes at the association ends.

2.4.1.2 Attribute Initializer MOIN uses a special constraint to express an initializer value for primitive type attributes. This initial value is used when new M1 instances are created. The use of this initializer is optional. It could also be used when an attribute is added to the metamodel and existing M1 data has to be updated to the new metamodel.

2.4.2 Query Infrastructure Besides JMI, MOIN offers a query infrastructure that can be used as an entry point into the repository. It allows the retrieval of model data based on the MOIN Query Language (MQL). MQL provides an SQL-like syntax to query the repository. An MQL query is specified against a M2 metamodel and queries M1 data. The MOIN Query Language (MQL) is strongly typed against the MOF metamodel. MQL queries return a result set which consists of multiple result records that contain references to the elements of the type that was specified in the query.

6In the actual implementation, this means that the M1 object at the “storage” end will contain a field that points to the other, linked element. In persisted state, it means that the link will be stored in the same partition as the respective element at the stored end. «enumeration» «enumeration» SeverityKind ChangeSequence 1 {ordered} 1..* ModelElementChange ChangeKind NON_BREAKING /severity:SeverityKind /severity:SeverityKind ADD changeSequence changes BREAKING_RESOLVABLE DELETE BREAKING_NOT_RESOLVABLE

ExistenceChange ConstrainsChange RefersToChange PropertyChange LinkChange kind:ChangeKind constrainedElement:ModelElement referrer:Reference affectedElement:ModelElement kind:ChangeKind affectedElement:ModelElement constraint:Constraint exposedEnd:AssociationEnd

MultiplicityTypeChange GeneralizesChange CanRaiseChange lower:Integer IsOfTypeChange superElement:GeneralizableElement except:Exception upper:Integer typedElement:TypedElement subElement:GeneralizableElement operation:Operation isOrdered:Boolean type:Classifier position:Integer position:Integer isUnique:Boolean

ContainsChange AttachesToChange AliasesChange PrimitiveTypeChange EnumerationTypeChange container:Namespace modelElement:ModelElement importer:Import propertyName:String containedElement:ModelElement tag:Tag imported:Namespace position:Integer position:Integer

BooleanChange DirectionKindChange ScopeKindChange VisibilityKindChange newValue:Boolean direction:DirectionKind scope:ScopeKind visibility:VisibilityKind

MultiValuedStringChange StringChange kind:ChangeKind AggregationKindChange EvaluationPolicyChange newValue:String value:String aggregation:AggregationKind evaluationPolicy:EvaluationKind position:Integer

Figure 4: The MOF change metamodel 3 CHANGES IN MOF-BASED METAMODELS 8

3 Changes in MOF-Based Metamodels

In this section, the types of changes that can applied to M2 metamodels will be described and classified depending on their impact on existing M1 data. First, a formal definition of metamodel changes will be presented, then, the single change types will be described and classified.

3.1 Definition For the description of metamodel changes, we introduce a Change Metamodel (see Figure 4). Instances of this metamodel describe an actual change to a metamodel as a sequence of single change steps, contained in a ChangeSequence element. As described in [AP03], all changes in a metamodel can be expressed as a sequence of either additions or deletions of elements and links, or modifications of a property. The Change Metamodel is also based on this assumption; the three base classes of the change metamodel cover the addition or deletion of elements (ExistenceChange), the modification of properties7 (PropertyChange) and the deletion or addition of links (LinkChange). These single change types will be described and classified in the following subsections. For the non-trivial cases, the classification of a change is expressed as an OCL constraint. These and other consistency constraints that are attached to the change metamodel are listed in Appendix B.1.

3.1.1 ExistenceChange This class describes the addition or deletion of an element, such as a class, an attribute, an association, etc. If an element is to be deleted, the attribute affectedElement references the element in the metamodel. In the case of an addition, it references a new element.

3.1.2 PropertyChange A property of a metamodel element represents an attribute in the MOF class of which the element is an 8 instance. Since in the MOF model, the attributes of the classes are only typed with DataTypes (and not with classes), we can specify an actual class in our metamodel for every property type. Furthermore, the propertyName field is only needed for the PrimitiveTypeChange. With multiplicity or enumeration types, there is only one attribute of the respective type in each MOF class, and so the change is unambiguous.

3.1.3 LinkChange This class represents all changes in features that are associations in the MOF model. This includes containment, inheritance (generalization) and typing, some of which are features that are not represented as a (visible) association in a model diagram. For associations that are ordered, the field position describes the position of a newly added element. For deletions, this value is ignored.

3.2 Prerequisites 3.2.1 Difference of Metamodels In general, there are two ways of determining the difference of two (meta-)models: Either the tracing of single changes or direct comparison. Both approaches have their advantages and drawbacks.

7When we talk about “properties”, we mean attributes of MOF model classes. However, since the notion “attribute” could be misinterpreted in some cases, we refer to them as properties. 8This can be somewhat confusing, since metamodel classes can have attributes themselves; however, these class attributes do not have values in the M2 level, but only in the M1 instances. 3 CHANGES IN MOF-BASED METAMODELS 9

Single changes to a metamodel can only be traced if the infrastructure which is used to edit the metamodel supports the recording of changes. This generates a sequence of atomic changesteps, which is at the same time the advantage and the disadvantage of this approach. On the one hand, single steps are often needed for a formal description of a larger change. With tracing, they do not have to be determined by an algorithm, as it is the case for the direct comparison; on the other hand, it is possible that some of these steps revert each other, for example a consequent addition and deletion of the same element. In other words, the set of changes is not necessarily minimal when using this method. If two metamodels are compared directly, an algorithm has to be found that determines a sequence of changes that describes the conversion of one metamodel version to another. The advantage of this approach is that the sequence of changes will be minimal if a proper algorithm is used, e.g. the one described in [CRGMW96]. However, it is more difficult to determine the atomicity of changes. For example, moving an attribute from a class to a superclass can be seen as a delete/add operation of two attributes with the same name, multiplicity and type, but also as a change of containment for the attribute. Of course, the latter makes it easier to make statements about the impact on M1 data.

3.2.2 Validation of M1 Model Data Instance data on the M1 level is always connected to a M2 metamodel, and in general, it cannot be used without knowledge about the metamodel.9 If there are changes in the metamodel, existing M1 data can become invalid. There are different ways of validating the conformance of M1 data to a metamodel. A general definition of model inconsistencies for UML is given in [MvdSD06]. The easiest way to do this is on interface level, e.g. the generated JMI interfaces. However, this definition is very strict and does not even allow minimal changes such as a change in the order of attributes.10 Furthermore, this definition of compatibility depends on the language used for the interfaces, which is Java for the JMI case. In MOIN, model data is stored in partitions, from where it is loaded and validated against the deployed metamodels. If M1 data refers to M2 elements that do not exist, these references are ignored and an error message is traced. Nevertheless, the M1 data can be read.

3.3 Classification In this subsection, the changes types are sorted by the classes of the change metamodel. In the single sections, the description of the impact of changes is then split up by the affected MOF classes.11 Here, we use the non-abstract MOF classes. Some changes are not applicable to MOIN because of unsupported types or because attributes are set to a certain value by standard. It is noted in the respective section if a feature is not supported by MOIN. We classifiy the changes into the three severities that are defined in [BGGK07]: non-breaking < breaking and resolvable < breaking and not resolvable

• A non-breaking change does not require any adaptation of existing M1 data, which is mostly true for additive changes to the metamodel. • For breaking and resolvable changes, an algorithm can be defined to migrate existing instances to the new metamodel version. • If a breaking and not resolvable change occurs, manual interaction is required to make existing data conformant with the new metamodel, if at all possible.

For certain M1 models, a change can have no effect although it is classified as breaking. In the following sections, we will always describe the worst case at first, and then mention the special cases where M1 data

9However, there are methods to determine metamodel information from M1 data, depending on the format in which they are stored. This problem is similar to the extraction of schema information from existing XML instances, as described in [MAC03]. 10See Section 5 for details. 11For changes in the metamodel, we regard neither the MOF-conformance nor the integrity of the metamodel — we suppose that the editor of a metamodel ensures these. Our interest lies in the M1 models and the changes that are necessary in order to make them conformant to the new M2 metamodel. 3 CHANGES IN MOF-BASED METAMODELS 10 is not affected by that change. However, there are generic cases that can be applied to all metamodel types: If an M2 element is modified, and no M1 instances exist for that element12, the change is non- breaking.

3.3.1 ExistenceChange This section is divided into the M2 classes of which affectedElement is an instance.

3.3.1.1 Class add The addition of Class elements is non-breaking. delete If classes are deleted, the corresponding M1 instances must also be deleted. This change can be breaking and not resolvable if a situation similar to Figure 5 occurs: The instance of Type2 has a link to an instance of Subtype1. If Subtype1 is deleted, the association still exists in the metamodel, since it is connected to the superclass Type1 of the deleted class. As a consequence of the deletion of Subtype1, all its instances and the links to these instances are also deleted, leaving only the instance of Type2. Now the model data is invalid, since there is no link to an instance of Type1, which is required by the minimum cardinality of 1 in the metamodel. This case is described by the severity constraint [SC-1]. In other situations, this change is breaking and resolvable.

Type1 1..* 0..1 Type2 Type1 1..* 0..1 Type2

M2 Subtype1

M1 :SubType1 :Type2 :Type2

Figure 5: Example: Deletion of a class makes M1 data invalid

3.3.1.2 Attribute add The effect of the addition of an attribute to an element depends on the minimum cardinality13 of that attribute. If the minimal cardinality is 0, then the change is non-breaking. If it is greater than 0, which means that attribute values have to exist, the change is breaking and not resolvable, as described in severity constraint [SC-2]. This is caused by the fact that MOF 1.4 does not support initializers for typed elements. Otherwise, the initial value could be set for non-initialized attributes. If an initial value for the attribute is specified elsewhere in the metamodel, the change is breaking and resolvable.14 If the containing element for the attribute has been added in the course of the change sequence, the addition of mandatory attributes is non-breaking since there are no M1 instances of this element.15 This is described in severity constraint [SC-2]. delete All attribute values have to be deleted. This change is breaking and resolvable.

3.3.1.3 Association add For associations, the same is true as for attributes: If the minimum cardinalities of the associ- ation’s ends are equal 0, then the change is non-breaking. If the minimum is greater than 0, the existing

12For classes, this also means that instances of any subtype must not exist either. 13 I.e. the field lower in the attribute multiplicity. 14In MOIN, there is a special constraint for attribute initializers. (See Paragraph 2.4.1.2) 15In case the newly added element is declared as a superclass of existing classes with possible M1 instances, these instances can become invalid; this fact is described in severity constraint [SC-6] of GeneralizesChange. 3 CHANGES IN MOF-BASED METAMODELS 11

M1 data may not conform to the new metamodel, and the change is breaking and not resolvable. If there are no instances of the element at the other end of the association, this change is non-breaking.16 In the example of Figure 6, several cases can occur when Assoc1x2 is added to the metamodel: If there are no instances of neither Type1 nor Type2, the change is trivially non-breaking. If there are instances of Type1, the change is still non-breaking, since the minimum cardinality of assoc1x2EndB is 0. If instances of Type2 exist, the change is breaking and not resolvable, since the minimum cardinality of assoc1x2EndA is 1, but there are no links for this association, as it has been newly added to the metamodel. delete The links in the M1 model have to be deleted. This change is breaking and resolvable. This is described in severity constraint [SC-3].

Type1 1..* Assoc1x2 0..1 Type2 assoc1x2EndA assoc1x2EndB Figure 6: Example: Association cardinality

3.3.1.4 AssociationEnd 17 Since an AssociationEnd is always contained in an Association , the effects for add/delete are the same as for an Association element.

3.3.1.5 Reference A Reference has no instances; it is to be understood as a convenient way to access links (which can be seen as instances of an Association). If references are added or deleted, the only change is in the interface definition of an element, which is on the M2 level. Thus, these changes are non-breaking.

3.3.1.6 Package add The addition of a Package is non-breaking. delete If a package is deleted, the impact on M1 data depends on how the contents of this package can be resolved. If the elements which were contained in the package can be resolved, the change is breaking and resolvable, otherwise ist is breaking and not resolvable.

3.3.1.7 Import add The addition of an Import is non-breaking. delete If all the elements which were imported by this Import can be resolved, this change is breaking and resolvable. Otherwise, it is breaking and not resolvable.

3.3.1.8 Tag The semantics of a Tag are not specified by MOF. This is why it is not possible to make a statement about the impact of a generic tag. However, there are tags which are relevant for JMI generation, see Paragraph 5.4.2.5, and there are special tags in MOIN, see Subsection 3.5.

3.3.1.9 Constraint add In general, the addition of a constraint is breaking and not resolvable. Constraints can be arbitrarily complex, so necessary changes in M1 data cannot be easily resolved. Also, constraints in a M2 model can be in different languages (MOF uses OCL in its own constraints), so a possible “impact analysis” of constraint changes would have to be language-specific. Even if we only regarded OCL, the analysis would exceed the scope of this work. However, there is one (trivial) special case; if there are no instances of the element affected by the new constraint (i.e., its context), the change is non-breaking. delete The deletion of a constraint is always non-breaking, since the restrictions for M1 data are reduced by this operation.

16 Here, the same is true as for Attribute: If the classes at the association’s end are newly added, there can be no new instances; also, in the case of existing subclasses, the severity is described in severity constraint [SC-6]. 17This is described in MOF constraint [C-33]. 3 CHANGES IN MOF-BASED METAMODELS 12

3.3.1.10 Constant add This change is non-breaking. delete If the constant is referenced somewhere in the M1 data, the change is breaking and not resolvable; otherwise, it is non-breaking.

3.3.1.11 Operation An Operation is specified on M2 level and does not have a representation on M1 level. Since it is a BehavioralFeature, it does not have instances, and its behaviour is only dependent on the state of an instance; if two instances are in the same state, i.e. all attribute values are the same in both instances, the operation behaviour will be identical. The addition or deletion of an operation does not have an effect on the M1 data; thus, this change is non-breaking.

3.3.1.12 Exception Exceptions, like operations, are specified on M2 level. A change of an Exception definition does not influence the persistence of M1 data; it is non-breaking.

3.3.1.13 Parameter Since a Parameter is always part of an Operation or Exception, a change is non-breaking.

3.3.1.14 DataType The DataType class is abstract in the MOF model; however, since the approach is the same for all subclasses of DataType, we will only describe it once here. add This change is non-breaking. delete If a DataType is deleted, all TypedElements of this type (in the M2 model) have to get another type or be deleted. However, this is an additional action18 which ensures metamodel consistency, and the changes made for this action have effects of their own. (See Paragraph 3.3.3.3) If the deletion of a Datatype does not cause changes in the M2 model, it is also non-breaking for the M1 data, since a DataType does not have M1 instances.

3.3.1.15 CollectionType CollectionType is not supported by MOIN.

3.3.1.16 AliasType AliasType is not supported by MOIN.

3.3.1.17 StructureField For a StructureField, the same is true as for DataType.

3.3.2 PropertyChange In this section, we analyse the changes in properties of MOF classes. Derived attributes are not regarded since they cannot be directly changed.

3.3.2.1 ModelElement name Elements can be resolved after a name change since every element has a unique identifier, the MOFid. If the infrastructure accesses the metamodel elements via the MOFid primarily,19 a name change which preserves the MOFid is non-breaking. Nevertheless, a refactoring must be performed on the M1 instances to guarantee the consistency with the metamodel. Thus, the overall change is breaking and resolvable. 18 Namely, an IsOfTypeChange. 19This is the way it is done in MOIN. 3 CHANGES IN MOF-BASED METAMODELS 13

annotation An annotation is only used for descriptive purposes20, so changes in this attribute are always non-breaking.

3.3.2.2 GeneralizableElement isRoot/isLeaf These properties can be seen as constraints which are only important for the consis- tency of the metamodel itself; thus, the M1 data is not affected by a change of these flags, the change is non-breaking. isAbstract If an abstract element is marked non-abstract, the change is non-breaking. If a non- abstract element is changed to abstract, its direct instances will have to be deleted. This change is breaking and resolvable. visibility If the visibility of an element is increased, the change is non-breaking; if it is decreased, the change is breaking and not resolvable. The visibility is always set to public_vis in MOIN.

3.3.2.3 Association isDerived If a non-derived association is set to derived, the links in the M1 data may become invalid if they do not conform with the derivation rule, which can be defined in an arbitrary way. So this change is breaking and not resolvable. If a derived association is set to non-derived, the change is non-breaking.21 This feature is always set to false in MOIN.

3.3.2.4 Class isSingleton If a singleton class is changed to non-singleton, this change is non-breaking. In M1 models, there can be at most one single element of this class, which is still valid after the class loses its singleton property. In the other direction, the change is only non-breaking if there is exactly one instance of the class. Otherwise, it is breaking and not resolvable, since there is no way to determine which instance should be the new singleton instance and which instances should be deleted. This feature is always set to false in MOIN.

3.3.2.5 Tag The effect of changes of a tag property cannot be universally described. See Paragraph 3.3.1.8.

3.3.2.6 Constraint expression Again, the semantics of a constraint can be arbitrarily complex, so general statements on the effect on M1 data cannot be made easily. The special case is the same as in Paragraph 3.3.1.9: If there are no M1 instances of the constrained element, the change is always non-breaking. language A change of this feature does not make sense without changing the expression itself. See above. evaluationPolicy The EvaluationPolicy determines the point of time when a constraint should be checked. This does not influence the compliance of static M1 data with the constraint; hence, a change of this property is non-breaking. A change of the evaluation policy does not have an effect in MOIN.

3.3.2.7 Feature scope If the scope is set from instance_level to classifier_level, it has to be assured that all instances of that element have the same value. If different values are existent, it is not clear which one should be chosen. So this change is breaking and not resolvable. In the other direction, if the scope is set from classifier_level to instance_level, the change is non-breaking. visibility See GeneralizableElement (Paragraph 3.3.2.2). This feature is always set to public_vis in MOIN.

20[MOF02], chapter 7.4.1 21In order to preserve as much data as possible, it would be a good idea to persist the links the way they were last calculated. 3 CHANGES IN MOF-BASED METAMODELS 14

3.3.2.8 StructuralFeature multiplicity If the range of the multiplicity is widened, the change is non-breaking; if it is narrowed, the change is breaking and not resolvable. isChangeable This feature is always set to true in MOIN.

3.3.2.9 Attribute isDerived See Association. (Paragraph 3.3.2.3). This feature is always set to false in MOIN.

3.3.2.10 Operation isQuery Since Operation is a M2 feature, a change of this feature is non-breaking.

3.3.2.11 Constant value Since Constant is a M2 feature, a change of this feature is non-breaking.

3.3.2.12 Parameter A Parameter can only be part of an Operation or an Exception, which are both M2 features.

3.3.2.13 AssociationEnd isNavigable A change in navigability does not have any effects on the M1 data. Therefore, this change is non-breaking. This feature is always set to true in MOIN. aggregation If an aggregation is changed from composite to none, this change is non-breaking. In the other direction, there are two cases: If a composition cycle is created, the change is breaking and not resolvable, since there could be links between instances which violate the composite closure rule: On the M1 level, an element must not be in the closure of a composite relation to itself; furthermore, an element can have at most one composite parent.22 If the metamodel does not contain a composition cycle after the change or if no links exist which will violate the composition closure rule, the change is non-breaking. This is described in detail in severity constraint [SC-4]. In Figure 7, an example of a composition cycle can be seen.

Type1 Type2 Type1 Type2

M2 Type3 Type3

M1 :Type1 :Type2 :Type1 :Type2

:Type3 :Type3

Valid in both versions Invalid in the new version Figure 7: Example: Composition cycle

multiplicity If the range of the multiplicity is widened, the change is non-breaking; if it is narrowed, the change is breaking and not resolvable.

22See [MOF02], chapter 8.11.2 3 CHANGES IN MOF-BASED METAMODELS 15

isChangeable This property describes the dynamic behaviour of a model. Static M1 data will still be valid if this property is changed, so the change is non-breaking. This feature is always set to true in MOIN.

3.3.2.14 EnumerationType labels The adding of labels constitutes a non-breaking change. If labels are removed or renamed, the change is generally breaking and not resolvable; however, if there are no fields in the M1 data with the affected enumeration label, the change is also non-breaking.

3.3.3 LinkChange This class describes the changes of links between elements in the metamodel. Since there is only a finite number of associations specified in MOF, we can describe all kinds of changes with the classes mentioned in the change metamodel. A link change can be the addition or the deletion of a link. This means that the change of a link is represented as delete and add. Since in many cases, a single delete does not make sense because the association must have an instance23, the description in the following paragraphs covers changes rather than single deletions or additions. (See Figure 4)

3.3.3.1 ContainsChange If the containment of an element is changed,24 several cases have to be regarded:

• If the new container is not a supertype, the element cannot be resolved, so the change is equal to the deletion of the element. The severity is equal to an ExistenceChange with the delete kind of the respective element type, which is breaking and not resolvable in the standard case. • If the new container is a supertype of the former container, the element will still be accessible for all M1 instances which reference it. However, if mandatory features (i.e. features with a multiplicity, where the minimum cardinality is greater than 0) are moved to a supertype, there is a possibility for M1 data to become invalid, which makes the change breaking and not resolvable. Of course, this does not apply to cases where all instances have values for that feature, e.g. because a new superclass was introduced and existing features are moved there. Then, the change is non-breaking, since all existing instances are still valid, and for the superclass, no instances exist, since it was newly created in the course of the metamodel change. This is described in detail by severity constraint [SC-5] and can also be seen in the example in Section 6.

In the example of Figure 8, an attribute is moved to a superclass. After this change, all instances of Type2 will still be valid, but instances of Type1 will become invalid since there are no values for attribute1.

3.3.3.2 GeneralizesChange add If a new supertype is added to an element, there are two possible cases. Firstly, if the new supertype or one of its supertypes contain mandatory features or there are mandatory association ends which point to these types, the change will be breaking and not resolvable, since the existing instances of the type will not have any values for these features. If the new supertype hierarchy does not contain such features, the change is non-breaking. The addition of a subtype is always non-breaking from the standpoint of the “super” element; thus, a generalization change should be observed from the subtypes’ view. delete If instances of the subtype are used as values for features which are typed with one of its direct or indirect supertypes, a deletion of the generalization association between those types will cause M1 data to become invalid if there are instances of these features, as seen for an association in Figure 9.

23 For example, a TypedElement must have a type; all elements except instances of Package must have a container (MOF constraint [C-1]), etc. 24 Technically, a change in containment consists of two single changes: one delete and one add change. Since all elements except Packages must be contained (MOF constraint [C-1]), it does not make sense to investigate the effects of single changes. The changes described here also define severities for the cases which were not regarded in Subsection 3.3.1. 3 CHANGES IN MOF-BASED METAMODELS 16

attribute1 has Type1 Type1 multiplicity 1..* attribute1:Integer

Type2 Type2 M2 attribute1:Integer

:Type1 :Type2 M1 attribute1 = 42

Figure 8: Example: Containment change

If the features are not mandatory, this problem can be resolved by removing the link between the instances, or in case of object-values attributes by a deletion of the attribute instance. This makes the change breaking and resolvable. If the features are mandatory, the change is breaking and not resolvable25. If the supertype contains structural features, the values of these features have to be deleted in the M1 instances and the change is breaking and resolvable; if the supertype does not contain any structural features, the change is non-breaking. The overall severity of the change is the highest severity of the two criteria mentioned. An exact specification can be found in severity constraint [SC-6]. In MOIN, there is no inheritance for packages.

Type1 Type2 Type1 Type2

M2 Subtype1 Subtype1

:SubType1 :Type2 M1 invalid

Figure 9: Example: Deletion of generalization leads to invalid M1 data

3.3.3.3 IsOfTypeChange The deletion of an IsOfType link always coincides with the creation of a new one, since the associ- ation end type has the multiplicity 1. There are two cases of a type change which are relevant here: 26 AssociationEnd and Attribute elements. If the new type is a supertype of the old type, the change can be non-breaking, since all instances will still be valid. However, there is a speciality for AssocEnd. If the situation is similar to Figure 10, existing M1 data will become invalid: In the example, EndB is moved to a supertype. In the M1 data, the instances of Type1 and SubType2 will still be valid after the change, since the association still exists. Only the instance of Type2 is invalid since there is no association to an instance of Type1 despite the minimum cardinality 1 of EndA. This makes the change breaking and not resolvable.

25This case is equal to the situation in Figure 5 on page 10. 26 The other instances of TypedElement are either not relevant for M1 data (Parameter, Constant) or are implicitely covered by these cases (Reference). 3 CHANGES IN MOF-BASED METAMODELS 17

If the new type is a subtype of the old type, the severity depends on the existent links and attribue values in the M1 data. If they are all type compatible with the change, i.e. that all instances are of the new type or one of its subtypes, the change is non-breaking. If there are instances of the old type which serve as a link end or attribute value, the change is breaking and not resolvable. If the new type is no sub- or supertype, the change is breaking and not resolvable. An exact specification can be found in severity constraint [SC-7].

Type1 Type2 Type1 1..* 0..1 Type2 1..* EndA EndB EndA 0..1 EndB M2 SubType2 SubType2

M1 :Type1 :SubType2 :Type2

Figure 10: Example: Type change on an association end

3.3.3.4 AttachesToChange A Tag does not have semantics which are specified in MOF, so the effects of a tag re-attachment cannot be described in general. See Paragraph 3.3.1.8.

3.3.3.5 ConstrainsChange This feature is ignored since we do not regard constraints. Anyway, a constraint is not only connected to an element via the Constrains association: In MOIN, the constraint language is OCL, and thus every constraint has an explicit context keyword. If an OCL constraint has a different context than the element to which it is connected via the Constrains association, MOIN will recognize this as an error.

3.3.3.6 RefersToChange 27 Changing the ReferencedEnd for a Reference constitutes a non-breaking change.

3.3.3.7 CanRaiseChange Since Operation and Exception are M2 elements, the change of this association is non-breaking.

3.4 Determination of Overall Severity 3.4.1 Problem Description Observing changes on an atomic level, like with the proposed change metamodel, has a fundamental disadvantage: There are certain kinds of changes which have a different effect on the metamodel if they are applied in combination. Normally, the overall severity of a change is the maximum of the severities of the single changes. But this is not always true. Think, for example, of the deletion of an element and the creation of another element with the same type and the same name. If a metamodel is modified this way, the only change is in the unique identifier of the affected element, everything else will be the same, which especially means that existing models will not become invalid in the new version of the metamodel. Another aspect of this matter is that there are kinds of changes in MOF which can be described as a single modification with the change metamodel, such as name changes or type changes for Typed•

27Note that the new end has to be compatible in terms of multiplicity, changeability and type (MOF constraints [C-21], [C-23] and [C-24]). If the new referenced end is not compatible with this, further changes in the metamodel will have to be performed to ensure consistency of the metamodel. 3 CHANGES IN MOF-BASED METAMODELS 18

28 Element , but others, like changes in generalization or containment, cannot be described as a single change.29 This has to be regarded when describing the severities for metamodel changes.

3.4.2 Solution Since metamodel changes are part of a ChangeSequence, it does not make much sense to analyse the effects of a single change operation. Furthermore, many operations cannot be applied as a single change, because they would lead to an inconsistent metamodel state. For example, if a Class is removed from its container, there has to be another change which adds it to a new container, because otherwise MOF constraint [C-1] would be violated. This is why the analysis of a change always has to regard the new metamodel version after all changes, which means that the new type and containment hierarchy must be known as well as the original hierarchies. If, like in our case, a metamodel change is described by the original metamodel and an instance of the change metamodel, the new metamodel has to be constructed first. We chose to describe the severities as OCL constraints which can be found in Appendix B.2. There, the helper functions [M-1] to [M-9] are used to calculate the new containment and type hierarchy. Based on these functions, the derived attribute severity of each ModelElementChange element can be determined. Since the severity of every ModelElementChange element depends on the other changes which are performed in the same ChangeSequence, the overall severity of such a sequence can be determined easily by finding the maximum severity. If a change sequence only consists of one change, this is still true, since the constraints are written in a way so that the result will still be correct if there are no other changes except one.

Type1 Type4 Type1 Type4

Type2 Type5 2.+ Type2 Type5

1. M2 Type3 Type3

invalid after change 1; i3a:Type3 i4:Type4 M1 becomes valid again after change 2

i3b:Type3 i5:Type5 invalid after each change

Figure 11: Example: Change in type hierarchy

3.4.3 Examples In this section, we will describe cases where a change sequence containing changes which would be breaking if performed as a single change becomes non-breaking in total.

3.4.3.1 Example for Hierarchy Change In the case of Figure 11, the class Type3 moves up one level in the type hierarchy: instead of being an indirect subtype of Type1, it becomes a direct subtype. If this change is described as two operations, deletion (1.) and creation (2.) of the generalization, the severity of the first operation is breaking,

28 The latter also covers the rerouting of an Association to another element in the metamodel. 29 This is caused by the fact that Generalization is an association on M3 level, and thus a link on M2 level. The associations in the metamodel are actually instances of the M3 classes Association and AssociationEnd. This can be a bit confusing since both are represented as a connector in the M2 class diagrams. 3 CHANGES IN MOF-BASED METAMODELS 19 according to Figure 9. This is also true as an overall severity for the instances i3b and i5, but not for the instances i3a and i4. Since Type3 becomes a subtype of Type1 again, the association between Type3 and Type4 conforms to the metamodel, and so the change is non-breaking for these two instances. If all M1 instances are valid after the change, the overall change is also non-breaking.

3.4.3.2 Example: Inverting Generalization Figure 12 shows a case where two changes are applied: The type of the association end EndB is changed 30 from Type2 to Type3, and the direction of the generalization is inverted. The interesting aspect of this configuration is the fact that each one of these changes would be breaking, but the combination of all of them is non-breaking.

Type1 Type2 Type1 Type2 EndA EndB EndA

EndB M2 Type3 Type3

M1 i1a:Type1 i2:Type2

i1b:Type1 i3:Type3

Figure 12: Example: Inversion of type hierarchy

3.4.3.3 Containment Change Changes in containment of element often occur as pairs, since all types of elements except pack- ages must be contained in another element. The movement of an element to a different container is described as a delete operation and an add operation. They can be identified as a pair by the identical containedElement. The severity of containment changes is described in Paragraph 3.3.3.1.

3.4.3.4 Delete and Add of Similar Elements A rather trivial case of severity weakening are operations which revert each other. Not all of these combinations can occur if the difference between two metamodels is determined by direct comparison. Addition and Deletion of an Element This change is always non-breaking and will not occur with direct comparison of metamodels since the versions are identical before and after the change. Deletion and Addition of an Element If an element is deleted, it cannot be exactly re-created, since a newly created element will get a different MOFid than the one which was deleted. However, it is possible to create an element with the same type and properties such as name, attributes etc. If the name is identical, the element will still be found if the infrastructure resolves elements by name when the MOFid is not found, as it is done in MOIN.

3.5 MOIN-Specific Changes 3.5.1 Storage The choice of the storage side has great effects on the layout of the persisted M1 data. If the storage side is changed to the other side of an Association in the metamodel, all existing M1 data will become invalid. This change is implementation-specific to MOIN and constitutes a breaking and resolvable change.

30 These steps actually each consist of two operations: deleting and adding of the generalization and of the IsOfType link. 3 CHANGES IN MOF-BASED METAMODELS 20

3.5.2 Attribute Initializer The attribute initializer constraint is used as the attribute value if new instances of an element are created. If this initial value is changed, existing M1 data cannot become invalid. The only problems are the semantics of this value: If existing data with this value is present, in can be mistaken for an initial value, and existing initial values can be mistaken for individually set values. 4 QUERY VISIBILITY OF CHANGES 21

4 Query Visibility of Changes

If metamodels are modified, it is possible that not only existing M1 data is affected by these changes, but also the result sets of existing MQL queries. As the query functionality of MOIN serves as an entry point for the access of M1 data, there may also be queries with an expected result set for existing M1 data. The changes to the metamodel can have two kinds of effects on the queries: • The result set can be different from the desired set. • The query itself can become invalid if it does not conform to the type system of the new version. In this section, we will investigate changes to the metamodel under the condition that the M1 data remains the same during the change. This means that the result set for an existing query and unmodified M1 data can only differ for a new metamodel if changes in the type hierarchy are part of the metamodel change. In all other cases, the result set will be the same or the query itself will become invalid. In general, additive changes to the metamodel cannot make a query invalid. If there are no M1 values for element features, the query engine will not return an entry in the result set for this element. On the other hand, changes which include the deletion of elements will make a query invalid only if the deleted element is part of the query, e.g. a class, an attribute or an association.

4.1 Changes Without Effects on Queries and Result Sets In general, all changes which are non-breaking according to the classifiations in Subsection 3.3 will not have an effect on query result sets. The only exception to this are changes to the generalization hierarchy, which are described in the next section.

4.2 Changes Affecting the Result Set Since the M1 data is not modified for the new metamodel, there can only be few cases which actually have an effect on the result set of a query. All of these cases are related to a change in type hierarchy. This is caused by the fact that queries normally operate on a type and all its subtypes. Only if the keyword withoutsubtypes is added to the from-clause, subtypes are not regarded. But when new types are added to the metamodel, there can be no instances for these types in the M1 data, since the types did not exist at the time the data was created. However, it is possible to add generalization between already existing classes, which adds the instances of the classes which are now subclasses to the result set.

Type1 i1:Type1 Query: select t1 from Type1 as t1 + i2:Type2 Result set before change: {i1, i2}

Type2 Type3 i3:Type3 Result set after change: {i1, i2, i3}

M2 M1

Figure 13: Query visibility: Adding generalization 4 QUERY VISIBILITY OF CHANGES 22

4.2.1 Adding Generalization Between Existing Types result set As seen in Figure 13, the addition of generalization between two existing classes may increase the size of the result set of a query if there are instances of the class which becomes the new subclass. query modification If the result set is intended to be the same after the metamodel change, the query of Figure 13 must be modified in a way so that all classes of the type hierarchy in the older version are mentioned explicitely. In this case, these are the types Type1 and Type2. So the result is the union of the result sets of the following queries: select t1 from Type1 as t1 withoutsubtypes ∪ select t2 from Type2 as t2 withoutsubtypes Listing 1: Query result set after generalization change

4.2.2 Deleting Generalization Between Existing Types result set In the other way, if a generalization is deleted, the size of the result set of a query may be reduced if there are instances of the subclass while the query operates over the superclass, as seen in Figure 14. A more complicated case where association are involved is shown in the next section. query modification In order to obtain the same result set with the new metamodel, the solution is again to include all classes explicitely in the from-clause. The result set is constructed analogously to Figure 13.

Type1 i1:Type1 Query: select t1 from Type1 as t1 i2:Type2 Result set before change: {i1, i2, i3}

Type2 Type3 i3:Type3 Result set after change: {i1, i2}

M2 M1

Figure 14: Query visibility: Deleting generalization

select t1 from Type1 as t1 withoutsubtypes ∪ select t2 from Type2 as t2 withoutsubtypes ∪ select t3 from Type3 as t3 withoutsubtypes Listing 2: Query preserving result set after generalization delete

4.3 Changes Making the Query Invalid The MOIN Query Language is strongly typed against M2 metamodels. This means that changes in the type system of a metamodel can make a query invalid. The validity of a query is checked in a preparation step before the actual query execution, and if it fails, the operation is aborted.31

31The validity of a query is independent from the existence of actual M1 data, since the type check is performed against the metamodel. 4 QUERY VISIBILITY OF CHANGES 23

4.3.1 ExistenceChange If elements which occur in the query are deleted from the metamodel, the query becomes invalid. This change is not resolvable. This applies to the following kinds of elements: Class, Attribute, Association (and the AssociationEnd elements contained in it) and DataType (for comparisons). The deletion of a Reference element is only breaking if the name of the reference differs from the name of the corresponding AssociationEnd. Otherwise, the link can be resolved via the association.

4.3.2 IsOfTypeChange If the type of a TypedElement is changed to a type which is not a supertype of the former type, the query becomes invalid. This cannot be resolved automatically since the semantics of a type change are sometimes ambiguous. For example, a TypeChange on an AssociationEnd element would cause a change in the from-clause of a query which includes a navigation over this association. However, it is not possible to determine which the new type of the from-clause should be, since it could be the type of the AssociationEnd itself or one of its subtypes, and for each of these, subtypes could be included or not.

4.3.3 ContainsChange For containment, the same is true as described in Subsection 3.3: The query will only become invalid if the affected element cannot be resolved after a containment change. If the element is still resolvable, the query can be executed normally.

4.3.4 GeneralizationChange The change of generalization can lead to queries becoming invalid if associations or features are accesed in the course of the query. If generalization between two classes is removed, a selection of elements of a subclass of the association end’s type will no longer be valid in the new metamodel version. This is the situation of Figure 9 on page 16, for which a critical query can be seen in Figure 15 below. The removal of the generalization makes the query invalid because the type SubType1 does not have a reference or association end called endB. The same is the case for attributes that are inherited from a superclass: If the generalization is removed, the query will become invalid if it accesses the attribute. Query: Type1 Assoc1x2 Type2 select s1 from SubType1 as s1, Type2 as t2 endA endB where s1.EndB = t2

SubType1 M2 Figure 15: Query visibility: Deleting generalization with association 5 JMI INTERFACES 24

5 JMI Interfaces

The primary means for access and manipulation model data in MOIN is the Java Metadata Interface (JMI). If changes are applied to underlying metamodels, the structure of these interfaces is also changed, possibly causing incompatibilities with existing tools using these interfaces. The compatibility for those interfaces is determined by Java type compatibility.32 Thus, we will investigate the impact of the change types defined in Section 3 on the Java type compatibility of the generated interfaces. The generation of interfaces from metamodels is a process which is currently implemented as a JMI Generator within MOIN. The generation logic lies in the actual Java implementation of the generator service, which makes it difficult to describe the impact of metamodel evolution on the generated interfaces. In this section, an alternative approach of JMI generation is presented: In order to describe the struc- ture of generated JMI interfaces, a JMI metamodel is introduced (see Figure 16). Using this metamodel, the generation of JMI interfaces can be described as a model transformation from MOF to the JMI metamodel, using a Transformation Metamodel (see Figure 20). The actual generation of Java classes can then be performed in a relatively simple process which is more or less a serialization of the JMI model instances. For the description of the change impact on JMI interface, we will first describe the severities of changes in JMI metamodel instances; then, a description of the effect of metamodel changes on JMI metamodel instances will follow. The combination of these two mappings delivers the impact of metamodel changes on the interfaces; this is presented as an overview table in Appendix A.

5.1 JMI Metamodel 5.1.1 Structure The JMI metamodel contains main classes which resemble the reflective interfaces of the JMI specification. These classes are:

• JmiBaseObject • JmiObject • JmiClass • JmiPackage • JmiAssociation • JmiStruct • JmiEnum

Each class represents a reflective interface: JmiObject represents RefObject, JmiClass represents Ref• 33 Class and so on. Instances of these “core” classes of the JMI metamodel are converted into actual Java classes in a generation step. All other instances of JMI metamodel classes are converted to methods, fields, comments or import statements, which are contained in the Java classes and are not classes of their own. 32When talking about Java type compatibility in this thesis, we refer to source compatibility, not binary compatibility. 33As a consequence of the self-descriptive nature of MOF, the reflective classes are themselves used as the single supertype if no other supertypes are specified for a JmiObject or JmiPackage element. In a pure modeling approach, this would be a jump between two modeling layers, which, on the other hand, is the idea behind reflection in Java. To represent this aspect of JMI design, the JMI Reflective Package is introduced in the next subsection. 5 JMI INTERFACES 25

5.1.2 Design Decisions 5.1.2.1 Links The JMI metamodel itself does not contain links to the original MOF classes to which the JMI objects correspond; this connection is established by the Transformation Metamodel (see next section). Also, classes which belong together semantically do not necessarily have a link in the metamodel, e.g. JmiObject and JmiClass. This is due to the fact that the Java interfaces, in this example, do not have a direct connection; nevertheless, the corresponding RefClass can be obtained for any RefObject via the reflective interface of JMI. The idea behind this JMI metamodel is to represent the structure of the generated interfaces rather than their semantical behaviour. In order to discover the semantics of the interfaces, the original metamodel classes can be accessed by the links of the Transformation Metamodel.

5.1.2.2 Inheritance The inheritance structure for the generated interfaces was only modeled in the points where the struc- ture is dependant from the metamodel layout. This is why there are classes that model the inheritance of instance interfaces and packages (ExtendsObjectStatement and ExtendsPackageStatement), but none for the class proxy and association interfaces. The reason for this can be seen in Figure 3 on page 5: The generalization structure of metamodels is only created for classes and packages on the Java side, but not for associations and class proxies; these interfaces always have the implicit supertypes RefAssociation and RefClass respectively.

5.1.2.3 Exceptions Exceptions are only modeled if they are part of the source metamodel. Most standard JMI operations throw a javax.jmi.reflect.JmiException. However, this was not modeled since it is a static property of every generated interface class, and as such, it can be included in the actual serialization process. 5 JMI INTERFACES 26 Statement Default Creator Creator Specific ExtendsPackage type Accessor ClassProxy * 1..* 1 JmiPrimitiveType ParameterAccessor ExceptionConstructor Creator Element * Accessor 1 Association JmiPackage «enumeration» 1 ParameterMultiplicity SINGLE SET LIST Struct Creator Accessor JmiClass NestedImported Jmi Exception name:String Modeled Operation throws JmiEnum labels:String Jmi JmiBaseObject packageName:String className:String Mutator Attribute Operation JmiAttribute name:String 1 Figure 16: The JMI metamodel type End2 Accessor input return Accessor Attribute JmiStruct End1 * {ordered} 0..1 Accessor JmiConstant JmiAnnotation name:String values:String text:String Link Remove Mutator Reference Add extendsStatement 1..* Link 1 * JmiObject Statement JmiReference ExtendsObject Accessor Reference object JmiParameter «reference» type:JmiBaseObject name:String multiplicity:ParameterMultiplicity Link Exists JmiAssociation 5 JMI INTERFACES 27

5.1.3 JMI Primitive Types Package The MOF specification defines six primitive types: Boolean, String, Integer, Double, Float and Long. These types are mapped to the Java types of the same name. In order to be able to express this relationship in the terms of the JMI metamodel, these Java types are modeled as instances of JmiPrimitiveType here. They can be used by any instance of the JMI metamodel by importing the primitive types package.

MOF primitive types Transformation JMI primitive types

Boolean source :PrimitiveType target JmiBoolean : (from PrimitiveTypes) Transformation JmiPrimitiveType

String source :PrimitiveType target JmiString : (from PrimitiveTypes) Transformation JmiPrimitiveType

Integer source :PrimitiveType target JmiInteger : (from PrimitiveTypes) Transformation JmiPrimitiveType

Double source :PrimitiveType target JmiDouble : (from PrimitiveTypes) Transformation JmiPrimitiveType

Float source :PrimitiveType target JmiFloat : (from PrimitiveTypes) Transformation JmiPrimitiveType

Long source :PrimitiveType target JmiLong : (from PrimitiveTypes) Transformation JmiPrimitiveType

Figure 17: The JMI primitive type package

5.1.4 JMI Reflective Package The purpose of the reflective interfaces in the JMI specification is twofold: On the one hand, the reflective interfaces are direct or indirect supertypes of each generated JMI interface, with the topmost type Ref• BaseObject (See Figure 3 on page 5). Secondly, the reflective interfaces hold methods which allow the gaining of meta-information on the JMI objects, such as an object representation of an elements meta- object, its MOFid or for the verification of model constraints. These reflective interfaces are represented as the elements of the reflective package in the JMI metamodel, as seen in Figure 18.

RefObject : RefClass : RefPackage : JmiObject JmiClass JmiPackage

Figure 18: The JMI reflective package 5 JMI INTERFACES 28

Transformation metamodel instance MOF-based JMI metamodel Generated metamodel instance Java code

:JmiObject Type1 :ClassTransformation name="Type1" public interface Type1 extends RefObject { ... } :ExtendsObjectStatement public interface Type2 extends Type1 { ... Type2 :JmiObject } :ClassTransformation name="Type2"

Figure 19: MOF to JMI transformation process

5.2 JMI Transformation Metamodel 5.2.1 Design The transformation from metamodels to instances of the JMI metamodel is described by an algorithm which contains the single steps of the transformation. In order to be able to associate the generated JMI model elements with the metamodel elements from which they were created, a Transformation Metamodel is used, which can be seen in Figure 20. The metamodel itself is quite simple and does not have a complex structure; it is merely used to model the 1:1 associations34 between the different MOF and JMI elements. The consistency requirements for the MOF-to-JMI transformation are described in Appendix B.3.2. These constraints describe much of the transformation semantics originating from the JMI specification [JMI02] itself; hence, they are not repeated here. For the generation of a JMI metamodel instance, a certain order of generation should be kept; other- wise, the elements could not be generated completely in one step, since references to elements which do not exist yet would not be instantiated. This is why the transformations should be performed in the way which is described in the next section.

5.2.2 Transformation process The transformation of a MOF-based metamodel into a JMI metamodel instance is the critical step in the MOF-to-JMI transformation described in this section. All logic of the generation lies in this step, and the second transformation step seen in Figure 19 should be understood as a serialization of instances of the JMI metamodel. The process is written in a pseudocode notation here; for a formal definition, OCL constraints are listed in the appendix. In the pseudocode notation, a phrase like “Element e1 in Element e2” means that the elements are linked by an instance of the Contains association. The transformation process is described as a procedure which takes the outermost package of the elements to be converted as an input parameter.

34 With one exception: Class maps to two interfaces, namely the instance interface JmiObject and the class proxy interface JmiClass. 5 JMI INTERFACES 29

procedure ConvertMofToJmi(Package p) create JmiPackage pjmi create PackageTransformation tP ackage tP ackage.source ← p tP ackage.target ← pjmi for all Class c in p do . create classes and proxies create JmiObject ojmi create JmiClass cjmi set ojmi.name according to [JMI02], section 4.7.2 cjmi.name ← ojmi.name + "Class" create ClassTransformation tClass tClass.source ← c tClass.target ← ojmi tClass.classProxyTarget ← cjmi for all Enumeration e in p do . create enumeration types create JmiEnum ejmi ejmi.name ← e.name ejmi.labels ← e.labels create EnumTransformation tEnum tEnum.source ← e tEnum.target ← ejmi for all StructureType s in p do . create structure types create JmiStruct sjmi create StructTransformation tStruct tStruct.source ← s tStruct.target ← sjmi create StructCreator cStruct and parameters cStruct.container ← s.container.transformation.target for all Class c in p do . create generalization hierarchy if c.supertype is empty then create ExtendsObjectStatement s c.extendsStatement.add(s) s.object ← JmiReflectivePackage::RefObject else for all Class csuper in c.supertype do create ExtendsObjectStatement s c.extendsStatement.add(s) s.object ← csuper create DefaultCreator d . create class constructor d.container ← c.transformation.classProxyTarget create input and output parameters create ClassProxyAccessor and parameters in psub for all Reference r in c do . create references create JmiReference rjmi create ReferenceAccessor accReference and parameters . respect multiplicity, isOrdered if r.multiplicity.upper =1 and r is changeable then create ReferenceMutator and parameters

rjmi.container ← r.container.transformation.target for all Attribute a in p do . create attributes create JmiAttribute ajmi create AttributeAccessor acc set name according to [JMI02], section 4.8.5 . booleans with is, others with get acc.container ← a.container.transformation.target create return parameter if a.isChangeable then 5 JMI INTERFACES 30

create AttributeMutator mAttr mAttr.container ← a.container.transformation.target create input parameters for all Operation o in p do . create modeled operations create ModeledOperation m create output parameter for all parameter pin of o with direction = in_dir do create input parameters

create OperationTransformation tOperation tOperation.source ← o tOperation.target ← m for all Association a in p do . create associations if ignoreLifeCycle = false then create JmiAssociation ajmi create LinkExists and parameters if End1 of a is navigable then create End1Accessor and parameters in ajmi . respect multiplicity, isOrdered if End2 of a is navigable then create End2Accessor and parameters in ajmi if End1 and End2 are changeable then create LinkAdd and parameters in ajmi create LinkRemove and parameters in ajmi

create AssociationTransformation tAssoc tAssoc.source ← a tAssoc.target ← ajmi create AssociationAccessor and parameters in pjmi

for all Package psub in p do . package operations ConvertMofToJmi(psub) create NestedImportedAccessor and parameters in pjmi if p.supertype is empty then . create package hierarchy create ExtendsObjectStatement s c.extendsStatement.add(s) s.package ← JmiReflectivePackage::RefPackage else for all Class psuper in p.supertype do create ExtendsPackageStatement s p.extendsStatement.add(s) s.package ← psuper for all element e in p do . create annotations if e.annotation not empty then create JmiAnnotation ajmi ajmi.text ← e.annotation ajmi.container ← a.container.transformation.target 5 JMI INTERFACES 31

5.3 Changes in JMI Interfaces In this subsection, the changes in the interfaces are described, using the JMI metamodel. For the description of the changes to JMI interfaces, the severities from Subsection 3.3 are used.

5.3.1 ExistenceChange The deletion of an element semantically corresponds to the deletion of a Java interface or parts of it, such as variables, methods or method parameters. In general, the deletion of an element is breaking and not resolvable, since existing tools which access the interface may rely on these elements. If they are missing after a change to the metamodel, code will break and cannot be resolved without knowledge about the semantics of the change. The severity of an addition of an element depends on the type of the element. It is described in detail in the following paragraphs.

5.3.1.1 JmiBaseObject add Adding a JmiBaseObject also results in the addition of a new Java interface class. This does not make any of the existing method calls invalid, so the change is non-breaking. delete If an element is deleted, existing code that refers to this element become invalid. This change is breaking and not resolvable.

5.3.1.2 JmiParameter If a parameter is added to or deleted from an operation, the calls to the resulting Java methods will be invalid because of the different numbers of parameters. However, this can be resolved automatically by changing these method calls in a way that all new parameters are set to the null value. Thus, the change is breaking and resolvable.

5.3.1.3 ExtendsObjectStatement add The addition of a superclass is additive if seen from the perspective of the generated interfaces. So the change is non-breaking. delete If an extends statement is deleted, which is semantically the removing of a superclass, the interface loses features, e.g. methods which are inherited from the superclass. If existing calls to the interface access these features, they will be invalid with the new version of the interface. Thus, the change is breaking and not resolvable.

5.3.2 PropertyChange 5.3.2.1 name A name change leads to a refactoring process in the interfaces, which can be performed automatically using a transformation model instance which connects to the metamodel. From there, the original name of the element can be retrieved from a change metamodel instance and refactoring can be performed, so the change is breaking and resolvable.

5.3.2.2 type If the type of a parameter is changed, there are two cases which have to be distinguished: • If the parameter is an input parameter, the severity is only non-breaking if the new type is a supertype of the old type. For all other cases, the change is breaking and not resolvable. • For a return parameter, the case is similar, but for the opposite direction in the type hierarchy: If the new type is a subtype of the old type, the change is non-breaking, in all other cases, it is breaking and not resolvable.

5.3.2.3 multiplicity If the multiplicity of a parameter is changed, the severity depends on the parameter direction and the kind of the change: 5 JMI INTERFACES 32

transformation 1..1 JmiObject 1..1 target (from JmiMetamodel) Class 1..1 1..1 Class (from Model) source transformation Transformation 1..1 1..1 JmiClass transformation classProxyTarget (from JmiMetamodel)

Package 1..1 1..1 Package 1..1 1..1 JmiPackage (from Model) source transformation Transformation transformation target (from JmiMetamodel)

Association 1..1 1..1 Association 1..1 1..1 JmiAssociation (from Model) source transformation Transformation transformation target (from JmiMetamodel)

Enumeration 1..1 1..1 Enum 1..1 1..1 JmiEnum (from Model) source transformation Transformation transformation target (from JmiMetamodel)

StructureType 1..1 1..1 Struct 1..1 1..1 JmiStruct (from Model) source transformation Transformation transformation target (from JmiMetamodel)

Attribute 1..1 1..1 Attribute 1..1 1..1 JmiAttribute (from Model) source transformation Transformation transformation target (from JmiMetamodel)

Reference 1..1 1..1 Reference 1..1 1..1 JmiReference (from Model) source transformation Transformation transformation target (from JmiMetamodel)

Operation 1..1 1..1 Operation 1..1 1..1 JmiOperation (from Model) source transformation Transformation transformation target (from JmiMetamodel)

Constant 1..1 1..1 Constant 1..1 1..1 JmiConstant (from Model) source transformation Transformation transformation target (from JmiMetamodel)

PrimitiveType 1..1 1..1 PrimitiveType 1..1 1..1 JmiPrimitiveType (from Model) source transformation Transformation transformation target (from JmiMetamodel)

Exception 1..1 1..1 Exception 1..1 1..1 JmiException (from Model) source transformation Transformation transformation target (from JmiMetamodel)

Figure 20: The transformation metamodel 5 JMI INTERFACES 33

For all kinds of parameters, change from SINGLE to SET or LIST is breaking and resolvable, since the Java type of the interface will change from a singular object type to collection type and vice versa; this can be resolved by adapting the code of the tool which is using the interface. For changes between unordered (SET) an ordered collections (LIST), the direction of the parameter has to be taken into account: If the multiplicity on an input parameter is changed from LIST to SET, the change is non-breaking, since the Java type java.util.List is a subtype of java.util.Collection. In the other direction, the change is breaking and resolvable. With a return parameter, the case is dual to the above mentioned: change from SET to LIST is non-breaking, change from LIST to SET is breaking and resolvable.

5.3.2.4 label 35 If the labels of a JmiEnum interface are changed , existing code which tries to access these labels will break, so this change is breaking and not resolvable.

5.3.3 LinkChange 5.3.3.1 Contains In this paragraph, the possible link changes are sorted by the type of the contained element. JmiOperation If an operation is moved to another container, the position of the new container in the supertype hierarchy of the old container is the only relevant criterion: If the new container is a supertype of the old container, the change is non-breaking. Otherwise, calls to this operation will become invalid, which makes the change breaking and not resolvable, unless a similar operation, i.e. with same name and compatible signature,36 is created and added to the old container. JmiAttribute/JmiReference/JmiConstant The severity for these elements is identical with JmiOp• eration. JmiAnnotation Annotations are represented as comments in the Java code and are such not relevant for compatibility, so these changes are always non-breaking.

5.3.3.2 Throws If an operation is altered in the number of kind of exceptions it throws, the change is breaking and not resolvable since existing code could try to handle exactly the kind of exceptions specified. If a modeled operation does not contain modeled exceptions, the type javax.jmi.reflect.JmiException is added to the throws statement to the interface, which is incompatible with the common supertype of modeled exceptions, javax.jmi.reflect.RefException.

5.4 Assignment of MOF Changes to JMI Changes In this subsection, the changes in MOF-based metamodels are assigned to changes in the JMI metamodel, for which the severities have been described above. Using this assignment, the impact of metamodel changes on the generated JMI interfaces can be determined. An overview of the metamodel changes an their impact can be seen in Appendix A.

5.4.1 ExistenceChange 5.4.1.1 Class add A new JmiObject an a new JmiClass element is created. The JmiObject instance is linked to RefObject via a newly created ExtendsObjectStatement. Two ElementCreators are created in the JmiClass element. A ClassProxyAccessor is created in the containing JmiPackage element. delete The above mentioned elements are deleted. 35 Which would be described in the change metamodel as a MultivaluedStringChange on the property labels of an JmiEnum 36I.e. the same number of parameters, of which every single parameter is of the same type or a supertype as the parameter at the this position in the old operation. 5 JMI INTERFACES 34

5.4.1.2 Attribute add A new JmiAttribute element is created, with the adjacent AttributeAccessor and Attribute• Mutator elements. For the containing JmiObject element, the corresponding ElementCreator is modified in a way that it is assigned a new input parameter, i.e. a new JmiParameter element is created, with the type equal to the new attribute’s type’s JMI representation. delete The JmiAttribute, AttributeAccessor and AttributeMutator elements and the JmiPa• rameter element are deleted.

5.4.1.3 Association add A new JmiAssociation element is created with its contained operations, depending on the properties of the original Association element: For each of the two AssociationEnd elements, the elements End1Accessor and End2Accessor are created if the isNavigable property is set to true. The types and multiplicities of these elements must match those of the original MOF elements. If for both ends, the isChangeable property is true, the LinkAdd and LinkRemove operations are created. A new AssociationAccessor element is created in the respective JmiPackage. delete The above mentioned elements are deleted.

5.4.1.4 AssociationEnd Since an association end cannot exist without an association in which it is contained, the effects of addition and deletion are those described in the paragraph above.

5.4.1.5 Reference add A new JmiReference object and a ReferenceAccessor element are created. If the Reference element has the property isChangeable and is single-valued, a ReferenceMutator element is also created. delete The above mentioned elements are deleted.

5.4.1.6 Package add A JmiPackage element is created. If it is nested in another package, a NestedImportedAccessor element is created. delete The above mentioned elements are deleted.

5.4.1.7 Import add A NestedImportedAccessor is created and added to the corresponding container package ele- ment. delete The above mentioned element is deleted.

5.4.1.8 Tag For the special tags javax.jmi.packagePrefix, javax.jmi.methodPrefix and javax.jmi.substituteName, changes to several elements occur. If the package prefix changes, all ele- ments whose transformation source lies in the affected package are changed in the property packageName. If the substitute name is changed, the element which was transformed from the element which contains the tag will be changed in the property className. The method prefix affects the className of elements of the type ModeledOperation which lie in the containment of the package that contains the tag.

5.4.1.9 Constraint Changes in constraints do not have an effect on the generated interfaces.

5.4.1.10 Operation add A new ModeledOperation element is created. delete The above mentioned element is deleted. 5 JMI INTERFACES 35

5.4.1.11 Exception add A new JmiException element is created with the contained ExceptionConstructor and Pa• rameterAccessor elements. delete The above mentioned elements are deleted.

5.4.1.12 Parameter add A new JmiParameter element is created. Its type property is set to the transformation target of the original Parameter element’s type. delete The above mentioned element is deleted.

5.4.1.13 DataType add For EnumerationType, StructureType or PrimitiveType, anew JmiEnum, JmiStruct or JmiPrim• itiveType element is created. In the case of JmiStruct, AttributeAccessor elements are created for every field of the structure type. delete The above mentioned elements are deleted.

5.4.1.14 StructureField add A new AttributeAccessor element is added to the containing JmiStruct element. delete The AttributeAccessor element is removed from the containing JmiStruct and is deleted.

5.4.2 PropertyChange 5.4.2.1 ModelElement name If no javax.jmi.substituteName tag is specified, the element’s className will change. annotation The property text of the contained JmiAnnotation element is changed.

5.4.2.2 GeneralizableElement isRoot/isLeaf A change in this property does not have an effect on the JMI interfaces. isAbstract If this property is set to true, no ElementCreator is generated in the proxy class Jmi• Class of the element. So a change from true to false causes the creation of the ElementCreator operation, a change from false to true causes the deletion of that element. visibility The JMI interface classes are only created for elements with visibility public_vis. This means that a change to public visibility causes the creation of the respective classes, so the impact is equal to an additive ExistenceChange. If the visibility is changed from public to protected or private, the impact on the interfaces is equal to the deletion of the element.

5.4.2.3 Association isDerived A change in this property does not have an effect on the JMI interfaces. See [JMI02, Chapter 4.2.5].

5.4.2.4 Class isSingleton The singleton semantics of a class only have an impact on the runtime behaviour of the generated JMI objects and do not influence the layout of the interfaces.

5.4.2.5 Tag If the field tagID is one of the the following:

• javax.jmi.packagePrefix • javax.jmi.methodPrefix • javax.jmi.substituteName a change in the property values has the same effect as the addition or deletion of these tags. 5 JMI INTERFACES 36

5.4.2.6 Constraint A change of properties of this type does not have an effect on the JMI interfaces.

5.4.2.7 Feature scope The accessors and mutators for features for the instance interfaces are generated in every case, so there is no change if the scope is changed. However, for the class proxies, the accessors and mutators are only created if the value is classifier_level. If this is changed to instance_level, the effect is the deletion of the accessors and mutators contained in the JmiClass objects; if an instance-scoped feature is changed to classifier-scoped, the effect is the creation of these elements. visibility As with GeneralizableElement, only elements with visibility level public_vis are gen- erated, so the effects of changing a public feature to non-public are the same as for the deletion of that feature; if a non-public feature is made public, the effects are the same as for the creation of that element.

5.4.2.8 StructuralFeature multiplicity The impact on interfaces only depends on the field upper and the isOrdered property. If upper is changed from >1 to 1 or vice versa, the property multiplicity in the corresponding Jmi• Parameter element will change between SINGLE, SET or LIST. If the isOrdered property is changed, the multiplicity will change between SET and LIST. isChangeable This parameter controls the generation of mutator methods in the interfaces. If it is set to false, no mutators are generated. So a change from true to false causes the deletion of the mutators, a change from false to true causes their creation.

5.4.2.9 Operation isQuery A change in this property does not have an effect on the JMI interfaces.

5.4.2.10 Constraint value A change in this property does not have an effect on the JMI interfaces.

5.4.2.11 Parameter direction If the direction of a parameter is changed, the link between JmiParameter to JmiOperation is changed between return and input. multiplicity This change alters the feature multiplicity of a JmiParameter in the same way as described for StructuralFeature.

5.4.2.12 AssociationEnd isNavigable This parameter defines whether the accessors for a JmiAssociation are created. So a change in this value leads to the creation or deletion of End1Accessor or End2Accessor elements. aggregation The aggregation semantics of model only have an impact on the runtime behaviour of the generated JMI objects and do not influence the layout of the interfaces. multiplicity This change alters the feature multiplicity of the association end accessors in the same way as described for StructuralFeature. isChangeable The creation of LinkAdd and LinkRemove elements is controlled by this parameter.

5.4.2.13 EnumerationType label This change alters the attribute labels of the corresponding JmiEnum element.

5.4.3 LinkChange 5.4.3.1 Contains A change in containment in a MOF model is reflected in various ways in a JMI model. The single cases are mentioned below, sorted by the type of the contained elements. Class Changes the containment of ClassProxyAccessor elements. Package Changes the containment of NestedImportedAccessor operations. 5 JMI INTERFACES 37

Association Changes the containment of AssociationAccessor operations. Feature Changes the containment of ReferenceAccessor, ReferenceMutator, AttributeAccessor and AttributeMutator operations. Operation Changes the containment of ModeledOperation elements. Constant Changes the containment of JmiConstant elements. Parameter affects the links between JmiParameter and JmiOperation. Constraints A change in the containment of constraints does not have an effect on the JMI interfaces. Tags A change in the containment of tags depends on the nature of the tag; see Paragraph 5.4.2.5.

5.4.3.2 Generalizes Class A change in the generalization hierarchy of classes alters the links between the ExtendsOb• jectStatement elements an the JmiObject elements involved. Package The case is the same as described above, for ExtendsPackageObject and JmiPackage elements.

5.4.3.3 IsOfType This change alters the type links between JmiParameter elements and the elements used as the type.

5.4.3.4 RefersTo A change in this association does have a direct effect on the generated interfaces; however, the change can cause further modifications to the MOF model instance to ensure the metamodel consistency, which may also have an impact on the generated interfaces.

5.4.3.5 CanRaise This change alters the throws links between JmiOperation and JmiException elements. 6 EXAMPLE 38

6 Example

In this section, the process of metamodel evolution is shown for a small example metamodel. Firstly, the change to the metamotel is described, then, the severities for existing M1 data are determined, including a detailed explanation of the determination process. The generation of a JMI metamodel instance and the Java interfaces is shown an overview diagram on the following pages.

6.1 Description The example used here is similar to the example in Figure 8 on page 16. It consist of a single class Type1 with a single Integer typed attribute attr1. The modification includes the addition of a new class, Type2, and the relocation of the attribute to this new class.37

Package1 Package1 Type2 attr1:int [1..1] Type1 attr1:int [1..1] Type1

Version 1 Version 2

Figure 21: Example metamodel

This change is described using instances of the change metamodel, as seen below. Change1 describes the addition of Type2, and Change2 represents the addition of the generalization link. The “relocation” of attr1 is described as a removal from its container in Change3 and an addition to the new container in Change4.

Change3 : ContainsChange Change1 : ExistenceChange kind=DELETE kind=ADD container=Type1 affectedElement=Type2 containedElement=attr1

Change2 : GeneralizesChange Change4 : ContainsChange kind=ADD kind=ADD superElement=Type2 container=Type2 subElement=Type1 containedElement=attr1

Figure 22: Change steps as Change Metamodel instances

37 The containment of an Attribute element in a Class element is technically represented as an instance of the MOF model association Contains. In the UML diagram, it is not depicted as a new frame with a line connection, but as a text field in the frame representing the Class element. 6 EXAMPLE 39

6.2 Severities regarding M1 instances 6.2.1 Single Changes Change1 The addition of a Class element is non-breaking according to severity constraint [SC-1] on page 55. Change2 The determination of the severity of this change is a bit more complex. If we look at severity constraint [SC-6] on page 57, we see that for an additive change, we have to check for mandatory features in the supertypes, meaning attributes or references which have a lower multiplicity greater than zero. In 38 our example, the only supertype is Type2, and a check for mandatory features yields attr1. So the addition of the generalization link would be breaking and not resolvable since for instances of the subtype Type1, the attribute attr1 may not be set. But in Version 1, the subtype of the new generalization link contains an attribute which is similar to attr1 (which means that it is at least identical in name, type and multiplicity; in this case, it is even the identical element), so the change is non-breaking. Change3 The severity of a containment change is described in severity constraint [SC-5] on page 56: Since the element which is removed from its container is added to a new container which is a supertype in the new generalization hierarchy, all instances of Type1 will still be valid as far as attr1 is regarded, and so the severity of this change is non-breaking. Change4 The same constraint specifies that the addition of a mandatory feature is non-breaking if the new container has been added in the course of the change sequence, since then there can be no instances of this element which could become invalid because of a missing attribute value. If the new container had been existant before, the change would have been breaking and not resolvable.

6.2.2 Overall The overall severity of this change can now be easily determined by calculating the maximum of all single severities, since the determination of single severites is based on all changes which occur within the change sequence. So the overall severity of this change sequence is also non-breaking.

6.3 Severities regarding Queries Since the overall severity for M1 data is non-breaking, all queries will still be valid after the change to the new version. Since the example is quite minimal, there are not many possible kinds of queries. The only possible query that includes an attribute would look like the following statement: select t1.attr1 from Type1 as t1

The result of this query is unchanged after a change in the metamodel, since no subclasses are added to classes that already exist in Version 1 of the metamodel.

6.4 Transformation into JMI model instance The example metamodel is transformed according to the transformation process described in Subsec- tion 5.2.2. The generated instance of the JMI metamodel is connected to the example metamodel via an instance of the transformation metamodel, in our example, instances of the classes PackageTransforma• tion and ClassTransformation. The transformed model and the generated code can be seen in 6.5.2 and Figure 6.5.2. According to Subsection 5.4, the single changes have the following effects on the generated JMI model:

• Change1 causes the creation of a JmiObject and a JmiClass element, in this case Type2 and Type2Class, and also the ExtendsObjectStatement element with a link to RefObject.

• Change2 causes the alteration of the object link of the ExtendsObjectStatement of Type1, which is changed from RefObject to Type2.

38The constraint requires us to check for features which exist after all changes of the sequence which the current change is part of. 6 EXAMPLE 40

• Change3 causes the deletion of the containment link between the JmiObject interface of Type1 and the JmiAttribute element representing attr1.

• Change4 causes the creation of a containment link between the JmiObject interface of Type2 and the JmiAttribute element representing attr1. The resulting JMI model has to fulfill the transformation constraints from Appendix B.3.2.

6.5 Severities regarding JMI interfaces 6.5.1 Single Changes In this subsection, the changes in the JMI interfaces of the example are assigned to the change severities according to Subsection 5.3. Change1 This change is purely additive, so the severity is non-breaking. Change2 The rerouting of the containment link augments the set of superclasses: The former su- pertype RefObject is still included since the new superclass Type2 is also a subclass of RefObject. So the change is additive and non-breaking. Change3 This change in containment would be breaking if it happened in isolation from other changes. But since the removed element is added to an element which is a superclass of the former container, the change is non-breaking. Change4 As an additive operation, this change is non-breaking.

6.5.2 Overall The overall severity is determined as the maximum of all single changes, which results in the severity type non-breaking for this example. This means that all applications which use the generated JMI interfaces will still be compatible in terms of Java source compatibility after the changes of this example. 6 EXAMPLE 41

Package1 javax.jmi.packagePrefix= Metamodel "mof.test" Type1 attr1:int [1..1] source source

Transformation Model transformation transformation :PackageTransformation :ClassTransformation

transformation transformation transformation

JMI Model

target classProxyTarget target :JmiPackage :JmiClass :JmiObject packageName="mof.test.package1" packageName="mof.test.package1" packageName="mof.test.package1" className="Package1Package" className="Type1Class" className="Type1"

type type type extendsStatement :ClassProxyAccessor :DefaultCreator :ExtendsObject name="getType1Class" name="createType1" Statement

return return object :JmiParameter :JmiParameter RefObject multiplicity=SINGLE multiplicity=SINGLE (from JmiReflectPackage)

:SpecificCreator return :JmiParameter :JmiAttribute extendsStatement name="createType1" multiplicity=SINGLE :ExtendsPackage Statement input :JmiParameter :JmiParameter return :AttributeAccessor name="attr1" package multiplicity=SINGLE name="getAttr1" RefPackage multiplicity=SINGLE (from JmiReflectPackage) type type :JmiParameter JmiInteger input :AttributeMutator name="newValue" (from JmiPrimitivePackage) name="setAttr1" type multiplicitiy=SINGLE

package mof.test.package1 public interface Package1Package extends javax.jmi.reflect.RefPackage { public Type1Class getType1Class(); } package mof.test.package1 public interface Type1Class extends javax.jmi.reflect.RefClass { public Type1 createType1(); public Type1 createType1(int attr1); } package mof.test.package1 public interface Type1 extends javax.jmi.reflect.RefObject { public int getAttr1(); public void setAttr1(int newValue); }

Figure 23: Example metamodel, Version 1 6 EXAMPLE 42

Package1

Metamodel javax.jmi.packagePrefix= Type2 source "mof.test" attr1:int [1..1]

source Type1 source

transformation transformation transformation Transformation Model :PackageTransformation :ClassTransformation :ClassTransformation

transformation transformation transformation transformation transformation

JMI Model

target classProxyTarget target :JmiPackage :JmiClass :JmiObject packageName="mof.test.package1" packageName="mof.test.package1" packageName="mof.test.package1" className="Package1Package" className="Type1Class" className="Type1"

type type type

:ClassProxyAccessor :DefaultCreator name="getType1Class" name="createType1" extendsStatement

return return :ExtendsObject :JmiParameter :JmiParameter Statement multiplicity=SINGLE multiplicity=SINGLE

:SpecificCreator return :JmiParameter name="createType1" multiplicity=SINGLE

input :JmiParameter name="attr1" classProxyTarget object target multiplicity=SINGLE :JmiClass :JmiObject packageName="mof.test.package1" packageName="mof.test.package1" className="Type2Class" className="Type2"

type type type :ClassProxyAccessor extendsStatement name="getType1Class" :DefaultCreator :ExtendsObject name="createType2" Statement

return :JmiParameter return object multiplicity=SINGLE :JmiParameter RefObject multiplicity=SINGLE (from JmiReflectPackage)

:SpecificCreator return :JmiParameter extendsStatement :JmiAttribute name="createType2" multiplicity=SINGLE :ExtendsPackage Statement input :JmiParameter :JmiParameter return :AttributeAccessor name="attr1" package multiplicity=SINGLE name="getAttr1" RefPackage multiplicity=SINGLE (from JmiReflectPackage) type type type :JmiParameter JmiInteger input :AttributeMutator name="newValue" (from JmiPrimitivePackage) name="setAttr1" type multiplicitiy=SINGLE

Figure 24: Example metamodel, Version 2 6 EXAMPLE 43

package mof.test.package1 public interface Package1Package extends javax.jmi.reflect.RefPackage { public Type1Class getType1Class(); public Type2Class getType2Class(); } package mof.test.package1 public interface Type1Class extends javax.jmi.reflect.RefClass { public Type1 createType1(); public Type1 createType1(int attr1); } package mof.test.package1 public interface Type2Class extends javax.jmi.reflect.RefClass { public Type2 createType2(); public Type2 createType2(int attr1); } package mof.test.package1 public interface Type1 extends mof.test.package1.Type2 { } package mof.test.package1 public interface Type2 extends javax.jmi.reflect.RefObject { public int getAttr1(); public void setAttr1(int newValue); }

Figure 25: JMI interfaces of example metamodel, Version 2 7 RELATED WORK 44

7 Related Work

Software evolution is a topic which has been researched intensely. The fields of this research include the evolution of programs, database schemas and models. However, the MOF standard does not include a specification for versioning, and thus the description of evolution of metamodels. In the MOF standard, it is suggested that this be included in an eventual implementation of a MOF repository.

7.1 MOF repositories Besides the MOIN project at SAP, there are also other implementations of a MOF repository, mostly in the academic field. The most popular commercial implementation is the Metadata Repository Project (MDR), which is part of Sun’s NetBeans platform. MDR offers features that ease the integration into the development envirionment, but it can also be used independently from the NetBeans IDE. It implements MOF 1.4, JMI and XMI and has a persistence layer which supports SQL databases, file persistence and transient memory persistence. It also features a graphical tool to explore the contents of the metadata repository. MDR is being developed as open source software. At Humboldt University in Berlin, a repository has been developped in the course of the A MOF project [Sch05]. It is based on MOF 2.0 and implements the sub-model CMOF. A MOF also includes a Java API of its own, rather than using JMI, and concentrates on easy development using meta-data rather than the storage of meta-data. Therefore, it only supports non-persistent model storage, which, together with the lack of JMI, distinguishes it from the repositories mentioned beforehand. However, A MOF supports the XMI standard for interchange with other modeling environments. The University of Darmstadt also runs a MOF 2.0 repository project, called MOFLON [AKRS06]. It is equipped with a graphical editor for metamodelling and also supports JMI and XMI. MOFLON supports OCL via the Dresden OCL compiler and also features the specification of integration patterns via a declarative QVT notation. The behaviour and transformation of models can be specified in the graphical editor with UML diagrams, from which Java code is generated automatically.

7.2 Metamodel Evolution The general process of Model Transformation targets the conversion of model data which is based on a certain metamodel into a model which is based on another metamodel. If two versions of a metamodel are used as these source and target metamodels, metamodels can be described by means of model trans- formation. For MOF, a transformation description language is defined in the Query/View/Transformation (QVT) standard [QVT07]. However, the QVT standard has not been widely adopted; furthermore, it is based on MOF 2.0, while this thesis is based on version 1.4. Since QVT and MOF 2.0 are not supported in MOIN, QVT was not used to describe the transformation steps in the evolution process and JMI conversion in this thesis. For the concurring metamodeling standard Eclipse Modeling Framework (EMF), a change meta-model is defined that follows a different concept than the one presented in this thesis. The EMF change metamodel is far smaller in size, and much more general. It basically describes one single element which respresents changes to all kinds of elements from the Ecore metamodel. Since EMF lacks a comprehensive specification document, more information about the EMF change metamodel can best be obtained by downloading the model definition sources on the Eclipse homepage.39 An approach for the classification of metamodel evolution cases based on EMF has been described by Becker et al. in [BGGK07]. The basic concept of the three change severities used in this thesis is defined there. Although based on EMF and Ecore, Becker et al. reject the EMF change metamodel for being too general for their purposes and propose its refinement. Since such a refinement is not presented in

39 http://www.eclipse.org/emf 7 RELATED WORK 45 the work, the focus lies on the procedural model for the migration of model data and a classification of changes based on the Ecore metamodel. Finding the difference of two models is a well-known problem; an algorithm for the determina- tion of deltas for any kind of hierarchically structured information is described by Chawathe et al. in [CRGMW96]. The authors use graphs for the representation of data and use graph transformation rules for the description of changes to the structure. Four basic editing operations are defined which are comparable to the base classes of the change metamodel used in this thesis. Additionally, a cost function and a matching algorithm for similar data is specified. In [AP03], a definition of metamodel changes is given for UML models in the form of editing oper- ations which are usable in both directions via a dual counterpart. Besides an algorithm that represents metamodel differences as applications of the editing operations mentioned beforehand, Alanen and Por- res also describe an algorithm for the minimization of change sequences. Furthermore, a version control mechanism for metamodels is proposed that targets the lack of versioning in the UML standard. 8 CONCLUSION 46

8 Conclusion

In this section, the work presented is summarized, followed by a description of the achievements in this thesis. Finally, an outlook to the future work, which may be based on this thesis, is given.

8.1 Summary After a description of the metamodeling technologies used, the problem of calculating the difference of two metamodels was discussed, presenting two fundamental techniques for the comparison of two metamodel versions. Independently from these techniques, a formalisation of changes to MOF-based metamodels was presented in the form of a change metamodel. Using this metamodel, the types of metamodel changes were evaluated regarding the severity of single and combined changes in terms of compatibility of existing model instances as well as interface compatibility. With regard to the SAP modeling infrastructure project MOIN, effects to the MOIN query infrastructure and to JMI interfaces were described, whereas the latter technology is a common standard which is also used by other MOF-based repositories.

8.2 Achievements The change metamodel allows a description of the metamodel evolution process using the means of modeling itself. Based on this, the severity of changes to a metamodel can be determined for single changes, and, more importantly, for complex change sequences using the change severity classification. This classification is implementation-independent and is only based on the MOF standard. It can be used to make statements about the compatibility of existing model instances to new versions of the metamodel on which they are based. The severity classification has been noted formally using OCL, so that the results of an automatic or manual classification can be checked by the respective modeling infrastructure. This makes it possible to use the results of the change classifications presented here in a platform-independent way. For manual evaluation of change severities, an overview table has been created. For the case of Java interfaces using JMI technology, a classification has also been presented which describes interface compatibility after metamodel changes. The process of the generation of JMI interfaces has been described as a model-to-model transformation by the means of a JMI metamodel.

8.3 Future Work In a metamodeling infrastructure which allows the comparison of different versions of the same metamodel, the classification presented in this thesis could be used to automatically determine the impact of a change to a certain metamodel on existing model data based on that metamodel. This would require an automatic calculation of a change metamodel instance from either two versions of a metamodel or from the current editing process of a persisted metamodel. The model editing tool could then determine the severity of the changes, which would enable the metamodel editor to decide about changes to the metamodel regarding the projected impact on existing data as well as interface compatibility of the generated software. The formal description of the JMI generation process could be used to create a generator tool which transforms metamodels into instances of the JMI metamodel. From these instances, the generation of actual Java files could be described as a serialization process of model instances. This would make it possible to evaluate the changes to JMI interfaces even if the transformation process is changed, since the change severities are calculated from the modeled description of the interfaces. The classification of metamodel changes then would enable metamodel editors and tool developers to estimate the effects of changes to existing metamodels, based on an automatic analysis. For users of the modeling tools, the formal description of metamodel evolution changes would ease the migration of their existing model data to new versions of that software. BIBLIOGRAPHY 47

Bibliography

[AKRS06] C. Amelunxen, A. Königs, T. Rötschke, and A. Schürr, MOFLON: A Standard-Compliant Metamodeling Framework with Graph Transformations, Model Driven Architecture - Foun- dations and Applications: Second European Conference (Heidelberg) (A. Rensink and J. Warmer, eds.), Lecture Notes in Computer Science (LNCS), vol. 4066, Springer Verlag, 2006, pp. 361–375. [AP03] Marcus Alanen and Ivan Porres, Difference and Union of Models, “UML 2003” – The Unified Modeling Language, Modeling Languages and Applications 6th International Conference, San Francisco, CA, USA, October 20–24, 2003, Proceedings (Berlin/Heidelberg) (Perdita Stevens, Jon Whittle, and Grady Booch, eds.), Lecture Notes in Computer Science, vol. 2863, Springer Verlag, 2003, pp. 2–17. [BGGK07] Steffen Becker, Thomas Goldschmidt, Boris Gruschko, and Heiko Koziolek, A Process Model and Classification Scheme for Semi-Automatic Meta-Model Evolution, Proc. 1st Workshop “MDD, SOA und IT-Management” (MSI’07), GiTO-Verlag, April 2007, pp. 35–46. [CRGMW96] Sudarshan S. Chawathe, Anand Rajaraman, Hector Garcia-Molina, and Jennifer Widom, Change Detection in Hierarchically Structured Information, Proceedings of the 1996 ACM SIGMOD International Conference on Management of Data, Montreal, Quebec, Canada, June 4-6, 1996 (H. V. Jagadish and Inderpal Singh Mumick, eds.), ACM Press, 1996, pp. 493–504. [Het06] Thomas Hettel, Impact Analysis of OCL Expressions, Master’s thesis, Institut für Ange- wandte Informatik und Formale Beschreibungsverfahren der Universität Karlsruhe, 2006. [HKV94] C. Huemer, G. Kappel, and S. Vieweg, Management of Data Model Evolution in Object- Oriented Database Systems, Proceedings of the International Symposium on Advanced Database Technologies and their Integration (ADTI’94) (Nara, Japan), October 1994. [HLR06] David Hearnden, Michael Lawley, and Kerry Raymond, Incremental Model Transformation for the Evolution of Model-Driven Systems, in Nierstrasz et al. [NWHR06], pp. 321–335. [JMI02] Java Community Process, JavaT M Metadata Interface (JMI) Specification, Version 1.0, June 2002, http://jcp.org/aboutJava/communityprocess/final/jsr040/index.html. [MAC03] Jun-Ki Min, Jae-Yong Ahn, and Chin-Wan Chung, Efficient extraction of schemas for XML documents, Inf. Process. Lett. 85 (2003), no. 1, 7–12.

[Mat03] Martin Matula, NetBeans Metadata Repository, , March 2003, http:// mdr.netbeans.org/MDR•whitepaper.pdf.

[MDA03] Object Management Group, MDA Guide Version 1.0.1, June 2003, http://www.omg.org/ docs/omg/03•06•01.pdf.

[MOF02] Object Management Group, Meta Object Facility (MOF) Specification, Version 1.4, April 2002, http://www.omg.org/docs/formal/05•05•05.pdf. [Mon93] Simon Monk, A Model for Schema Evolution in Object-Oriented Database Systems, February 1993. [MvdSD06] Tom Mens, Ragnhild van der Straeten, and Maja D’Hondt, Detecting and Resolving Model Inconsistencies Using Transformation Dependency Analysis, in Nierstrasz et al. [NWHR06], pp. 200–214. BIBLIOGRAPHY 48

[NR88] Gia-Toan Nguyen and Dominique Rieu, Schema Evolution in Object-Oriented Database Sys- tems, Tech. Report 947, INRIA & IMAG, Laboratoire de Génie Informatique, Grenoble, France, December 1988. [NWHR06] Oscar Nierstrasz, Jon Whittle, David Harel, and Gianna Reggio (eds.), Model Driven En- gineering Languages and Systems, 9th International Conference, MoDELS 2006, Genova, Italy, October 1-6, 2006, Proceedings, Lecture Notes in Computer Science, vol. 4199, Berlin/Hei- delberg, Springer Verlag, 2006.

[OCL06] Object Management Group, OCL 2.0 Specification, Version 2.0, May 2006, http://www. omg.org/docs/formal/06•05•01.pdf. [PK97] Anne Pons and Rudolf K. Keller, Schema Evolution in Object Databases by Catalogs, IDEAS ’97: Proceedings of the 1997 International Symposium on Database Engineering & Appli- cations (Washington, DC, USA), IEEE Computer Society, 1997, p. 368. [Pla08] Hasso Plattner, Trends and Concepts in the Software Industry I, Lecture Notes, Universität Potsdam, 2008, http://epic.hpi.uni•potsdam.de/pub/Home/ TrendsAndConceptsI2008/TuK2008_CompleteScript.pdf. [PÖ97] Randel J. Peters and M. Tamer Özsu, An Axiomatic Model of Dynamic Schema Evolution in Objectbase Systems, ACM Transactions on Database Systems 22 (1997), no. 1, 75–114. [QVT07] Object Management Group, Meta Object Facility (MOF) 2.0 Query/View/Transformation Specification, July 2007, http://www.omg.org/docs/formal/08•04•03.pdf.

[Sch05] Markus Scheidgen, On Implementing MOF 2.0 – New Features for Modelling Language Ab- stractions, 2005. [Spr03] Jonathan Mark Sprinkle, Metamodel Driven Model Migration, Ph.D. thesis, Vanderbilt Uni- versity, Nashville, Tennessee, USA, August 2003. GLOSSARY 49

Glossary

Application Programming Interface (API) The interface provided by a system, library or application in order to exchange data or provide services.

Eclipse Modeling Framework (EMF) A modeling framework based on the Eclipse platform. Java Metadata Interface (JMI) A mapping between Java and MOF. It provides a standard interface for access, manipulation and exchange of MOF-based metadata in Java.

Meta Object Facility (MOF) Formal language and framework for specifying metamodels definded by the OMG. MOF is used to define how meta data is organized.

Model-Driven Architecture (MDA) A software engineering approach defined by the OMG, using platform- independent models and domain specific languages.

Modeling Infrastructure (MOIN) SAP technology which provides a MOF-based meta-model repository and OCL integration.

MOF identifier (MOFid) Permanent, unique identifier that every MOF element posesses. This identi- fier is generated and bound to the object when it is created and cannot be changed for the lifetime of the object.

MOIN Query Language (MQL) The API of MOIN’s query infrastructure, which describes the syntax of the query language supported by MOIN.

Object Constraint Language (OCL) Formal, side effect free language to describe constraints on MOF- based models. These constraints can be invariants, pre- and post conditions and also query result definitions.

Object Management Group (OMG) A consortium that defines standards for modeling of programs, systems and business processes. Most prominent OMG standards are CORBA, UML and MOF.

Query/View/Transformation (QVT) A standard for the description of model transformation defined by the OMG, based on MOF 2.0 and OCL 2.0.

Unified Modeling Language (UML) A widely used graphical language for object modeling and speci- fication. OMG standard.

XML Metadata Interchange (XMI) XML-based interface for serialization of metadata, mainly used for import and export of metamodels. APPENDIX A CHANGE SEVERITIES OVERVIEW 50 affected JMI elements/comments JmiClass JmiAttribute, ElementCreator AssociationAccessor JmiReference JmiPackage, NestedImportedAccessor NestedImportedAccessor dependent from tag ID see section 5.4.2.5 all elements ModeledOperation X X X X X X bn ) ) X X X X X X X X br ( ( X X X X X X X X X X X nb JMI severity , no initializer , no instances , initializer exists 0 0 0 0 > = 0 > > = 0 > Association comments additive special case, see constraintother [SC-1] cases minimum cardinality minimum cardinality minimum cardinality minimum cardinality minimum cardinality minimum cardinality same as for contents resolvable contents not resolvable elements resolvable otherwise elements not resolvable in general no constrained elements less limitations for M1 data X X X X X X bn X X X X X X br X X X X X X X X X X X X X M1 severity nb add add add add add add add add add delete delete delete delete delete delete delete delete Tag Class Import Package Attribute Reference Operation Constraint Association AssociationEnd MOF change type ExistenceChange Appendix A Change Severities Overview APPENDIX A CHANGE SEVERITIES OVERVIEW 51 false → JmiException ModeledOperation, JmiParameter JmiEnum, JmiStruct JmiStruct all elements JmiObject, JmiClass JmiPackage JmiClass, JmiObject all elements Attribute/ReferenceMutator, ModeledOperation see section 5.3.2.3 Attribute/ReferenceMutator JmiAttribute ModeledOperation see section 5.3.2.3 true Attribute/ReferenceAccessor, ) ) ) X X X X X X X X X X X X ( ( ( X X X X X X X ) ) ) X X X X X X X X X X X X X X X X X X X X X X ( ( ( in MOIN) in MOIN) instance_level classifier_level → → public_vis public_vis in MOIN in MOIN true true true true false false false false true true → → → → → → → → refactoring, unique ids true false increase (always decrease true false true false no effect in MOIN instance_level classifier_level increase (always decrease widening narrowing always true false always X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X add add add add value name scope isLeaf delete delete delete delete delete isRoot isQuery visibility visibility language direction isDerived isDerived isAbstract expression annotation isSingleton isNavigable multiplicity multiplicity isChangeable evaluationPolicy Class Feature DataType Constant Exception Parameter Attribute Operation Parameter Constraint Association ModelElement StructureField AssociationEnd StructuralFeature PropertyChange GeneralizableElement APPENDIX A CHANGE SEVERITIES OVERVIEW 52 true true false → → → false see section 5.3.2.3 true false JmiEnum various depends on kind ofsee element section 5.3.2.2 JmiException ) ) X X X X X X X X X ( ( ) ) X X X X X X X X X X X X X X X X X X ( ( , composition closure none → composite → composite none rule violated closure rule not violated widening narrowing addition delete; general case delete; no M1 data with this value not mandatory; to supertype not mandatory; to othermandatory; type to supertype mandatory; to new ormandatory; abstract to supertype other type supertype contains mandatory featuresassociations or supertype containstures or non-mandatory associations fea- supertype contains no featurestions or associa- no associations to supertypepatible; or new features type in com- no supertype associations to supertypepatible; or no type new features com- supertype in has supertype adjacent mandatoryation associ- ends; change notsupertype type has compatible adjacent non-mandatory as- sociation ends; change not typenew compatible type is supertype;new general type case is supertype new type is subtype andcompatible instances are type new type is no sub- or supertype X X X X X X X X X X X X X X X X X X X X X X X X X X X add labels delete multiplicity aggregation isChangeable Contains IsOfType RefersTo CanRaise (see [SC-5]) (see [SC-6]) (see [SC-7]) Generalizes EnumerationType LinkChange APPENDIX B OCL CONSTRAINTS 53

Appendix B OCL Constraints B.1 Change Metamodel Constraints [CM-1] MultiplicityChangeApplicability A MultiplicityChange can only be applied to elements of the type StructuralFeature, AssociationEnd, Parameter and CollectionType. context MultiplicityChange inv: self.affectedElement.oclIsKindOf(StructuralFeature) or self.affectedElement.oclIsTypeOf(AssociationEnd) or self.affectedElement.oclIsTypeOf(Parameter) or self.affectedElement.oclIsTypeOf(CollectionType)

[CM-2] DirectionChangeApplicability A DirectionChange can only be applied to elements of the type Parameter. context DirectionChange inv: self.affectedElement.oclIsTypeOf(Parameter)

[CM-3] AggregationChangeApplicability An AggregationChange can only be applied to elements of the type AssociationEnd. context AggregationChange inv: self.affectedElement.oclIsTypeOf(AssociationEnd)

[CM-4] ScopeChangeApplicability A ScopeChange can only be applied to elements of the type Feature. context ScopeChange inv: self.affectedElement.oclIsKindOf(Feature)

[CM-5] EvaluationPolicyChangeApplicability An EvaluationPolicyChange can only be applied to elements of the type Constraint. context EvaluationPolicyChange inv: self.affectedElement.oclIsTypeOf(Constraint)

[CM-6] VisibilityChangeApplicability A VisibilityChange can only be applied to elements of the type GeneralizableElement, Import and Feature. context VisibilityChange inv: self.affectedElement.oclIsKindOf(GeneralizableElement) or self.affectedElement.oclIsTypeOf(Import) or self.affectedElement.oclIsKindOf(Feature) APPENDIX B OCL CONSTRAINTS 54

[CM-7] StringChangeValidNames Only String properties that exist in MOF can be changed. context StringChange inv: let ae = self.affectedElement in Set{"name", "annotation"} •> includes(self.propertyName) or (ae.oclIsTypeOf(Tag) and self.propertyName = "tagID") or (ae.oclIsTypeOf(Constraint) and Set{"expression", "language"} •> includes(self.propertyName)) or (ae.oclIsTypeOf(Constant) and self.propertyName = "value") or (ae.oclIsTypeOf(EnumerationType) and self.propertyName = "labels")

[CM-8] MultivaluedStringChangeValidNames Only multivalued String properties that exist in MOF can be changed. context MultivaluedStringChange inv: (self.affectedElement.isTypeOf(Tag) and self.propertyName = "values") or (self.affectedElement.isTypeOf(EnumerationType) and self.propertyName = "labels")

[CM-9] BooleanChangeValidNames Only Boolean properties that exist in MOF can be changed. context BooleanChange inv: let ae = self.affectedElement in (ae.oclIsTypeOf(Import) and self.propertyName = "isClustered") or (ae.oclIsKindOf(GeneralizableElement) and Set{"isRoot", "isLeaf", "isAbstract"} •> includes(self.propertyName)) or ((ae.oclIsKindOf(StructuralFeature) or ae.oclIsTypeOf(AssociationEnd)) and self.propertyName = "isChangeable") or ((ae.oclIsTypeOf(Association) or ae.oclIsTypeOf(Attribute)) and self.propertyName = "isDerived") or (ae.oclIsTypeOf(AssociationEnd) and self.propertyName = "isNavigable") or (ae.oclIsTypeOf(Operation) and self.propertyName = "isQuery") or (ae.oclIsTypeOf(Class) and self.propertyName = "isSingleton") APPENDIX B OCL CONSTRAINTS 55

B.2 Severity Constraints Note: This section makes heavy use of the helper functions defined in Appendix B.4. [SC-1] ExistenceChange: Class context ExistenceChange inv: (self.affectedElement.oclIsTypeOf(Class)) implies if (self.kind=ADD) then self.severity=NON_BREAKING else •• (self.kind=DELETE) if (self.newAssocEnds(self.affectedElement) •> exists(end| end.multiplicity.lower > 0 and self.affectedElement.allSupertypes() •> exists(t| t=self.changeSequence.newType(end)))) then self.severity = BREAKING_NOT_RESOLVABLE else self.severity = BREAKING_RESOLVABLE endif endif

[SC-2] ExistenceChange: Attribute context ExistenceChange inv: (self.affectedElement.oclIsTypeOf(Attribute)) implies if (self.kind=ADD) then if (self.affectedElement.multiplicity.lower = 0) then self.severity = NON_BREAKING else •• check if containing element has been newly added if (self.changeSequence.changes •> exists(c| c.oclIsTypeOf(ExistenceChange) and c.kind = ADD and c.newContains(c.affectedElement) •> contains(self.affectedElement))) then self.severity = NON_BREAKING else self.severity = BREAKING_NOT_RESOLVABLE endif endif else •• (self.kind=DELETE) self.severity = BREAKING_RESOLVABLE endif

[SC-3] ExistenceChange: Association context ExistenceChange inv: (self.affectedElement.oclIsTypeOf(Association) and self.kind=ADD) implies if (self.affectedElement.contents •> select(e|e.oclIsTypeOf(AssociationEnd)) •> forAll(a|a.multiplicity.lower = 0)) then self.severity = NON_BREAKING else •• check if the types on the other sides have been newly added if (self.affectedElement.contents •> select(e| e.oclIsTypeOf(AssociationEnd) and e.multiplicity.lower > 0) •> forAll(a|self.changeSequence.isNewElement(a.otherEnd().type))) then self.severity = NON_BREAKING else self.severity = BREAKING_NOT_RESOLVABLE endif endif APPENDIX B OCL CONSTRAINTS 56

[SC-4] AggregationKindChange context AggregationKindChange inv: let ae = self.affectedElement in ae.oclIsTypeOf(AssociationEnd) implies if (ae.aggregation=none and self.aggregation=composite) then •• check for composition cycles if (ae.otherEnd().type.allCompositeChildren() •> contains(ae)) then self.severity = BREAKING_NOT_RESOLVABLE else self.severity = NON_BREAKING endif else self.severity = NON_BREAKING endif

[SC-5] ContainsChange context ContainsChange inv: (self.container.oclIsTypeOf(Class) and self.containedElement.oclIsKindOf(StructuralFeature)) implies if (self.kind=DELETE) then if self.changeSequence.changes •> exists(c| c.oclIsTypeOf(ContainsChange) and c.kind = ADD and (c.containedElement = self.containedElement or c.containedElement.similar(self.containedElement)) and self.newSupertypesExtended(self.container) •> contains(c.container)) •• feature moved to supertype then self.severity = NON_BREAKING •• feature deleted or moved elsewhere else self.severity = BREAKING_RESOLVABLE endif

else •• (self.kind=ADD) if (self.containedElement.multiplicity.lower > 0) then •• mandatory feature if (self.changeSequence.isNewElement(self.container)) then •• containing class has been newly added if (self.newSubtypes(self.container) •> select(s|not self.changeSequence.isNewElement(s)) •> forall(s| s.containedElement •> select(e|e.oclIsKindOf(StructuralFeature) •> exists(f|f.similar(self.containedElement)))) or self.newSubtypes(self.container) •> isEmpty()) •• element is in all pre•existent subclasses then self.severity = NON_BREAKING •• pre•existent subclasses without this feature else self.severity = BREAKING_NOT_RESOLVABLE endif •• mandatory feature added to a pre•existent class else self.severity= BREAKING_NOT_RESOLVABLE endif •• non•mandatory feature else self.severity = NON_BREAKING endif endif APPENDIX B OCL CONSTRAINTS 57

[SC-6] GeneralizesChange context GeneralizesChange inv: •• the "super" element of the change plus all its supertypes in the old metamodel let selfAndOldSuper = self.superElement.allSupertypes() •> including(self.superElement) in •• the "super" element of the change plus all its supertypes after all other changes let selfAndNewSuper = self.newSupertypesExtended(self.superElement) •> including(self.superElement) in •• all the contained structural features in selfAndNewSuper after all changes let newSuperFeatures = selfAndNewSuper •> iterate(i:GeneralizableElement; y:Set(ModelElement) = Set{} | y •> including(self.newContains(i))) •> select(e|e.oclIsOfType(StructuralFeature)) in •• all association ends in the supertypes of superElement that exist after all changes let newSuperAssocEnds = (selfAndNewSuper •> iterate(i:GeneralizableElement; y:Set(AssociationEnd) = Set{} | y •> including(self.newAssocEnds(i))) in •• association ends on the old supertypes let oldSuperAssocEnds = self.changeSequence.oldAssocs() •> collect(containedElement) •> select(e| e.oclIsTypeOf(AssociationEnd) and selfAndOldSuper •> includes e.type) •• association ends on new supertypes; regard only ends already existing in the old version let newExistingSuperAssocEnds = self.newAssocEnds(selfAndNewSuper) •> intersection(self.changeSequence.oldAssocs() •> collect(containedElement)) if (self.kind = ADD) then •• check for mandatory features in supertypes if (newSuperFeatures •> exists(f|f.multiplicity.lower > 0 and not self.subElement.containedElement •> exists(e|e.similar(f))) or •• check for mandatory associations in supertypes newSuperAssocEnds •> exists(end|end.otherEnd().multiplicity.lower > 0 and not self.oldAssocs() •> collect(containedElement) •> includes(end))) then self.severity = BREAKING_NOT_RESOLVABLE else •• check for non•mandatory features in supertypes if (newSuperFeatures •> exists(f|f.multiplicity.lower = 0 and not self.subElement.containedElement •> exists(e|e.similar(f))) or •• check for non•mandatory associations in supertypes newSuperAssocEnds •> exists(end|end.otherEnd().multiplicity.lower = 0 and not self.oldAssocs() •> collect(containedElement) •> includes(end))) then self.severity = BREAKING_RESOLVABLE else self.severity = NON_BREAKING endif endif else •• (self.kind = DELETE) if oldSuperAssocEnds•>isEmpty() or newExistingSuperAssocEnds.includesAll(oldSuperAssocEnds) then •• no associations in the new supertype hierarchy or type compatible if (not superFeatures •> isEmpty() and superFeatures.includesAll( self.superElement •> collect(containedElement) •> select(e|e.oclIsTypeOf(StructuralFeature)))) then self.severity = BREAKING_RESOLVABLE else self.severity = NON_BREAKING endif else •• association to supertypes exists; change not type compatible if AssociationEnds.allInstances() •> excluding(a|self.isNewElement(a)) •> exists(e| selfAndOldSuper •> excluding(self.newSuperTypes(subElement)) •> exists(t|t.type = e) and e.multiplicity.lower>0) then self.severity = BREAKING_NOT_RESOLVABLE else self.severity = BREAKING_RESOLVABLE endif endif APPENDIX B OCL CONSTRAINTS 58

[SC-7] IsOfTypeChange context IsOfTypeChange inv: if (self.typedElement.oclIsTypeOf(Attribute)) then if (self.newSupertypes(self.typedElement)) •> includes(self.type) then self.severity=NON_BREAKING else self.severity=BREAKING_NOT_RESOLVABLE endif else if (self.typedElement.oclIsTypeOf(AssociationEnd)) then if (self.newSupertypes(self.typedElement)) •> includes(self.type) then if (self.typedElement.otherEnd().multiplicity.lower>0) then self.severity=BREAKING_NOT_RESOLVABLE else self.severity=NON_BREAKING endif else self.severity=BREAKING_NOT_RESOLVABLE endif endif endif

[SC-8] MultiplicityChange context MultiplicityChange inv: if (affectedElement.multiplicity.lower >= self.lower and affectedElement.multiplicity.upper <= self.upper) then self.severity=NON_BREAKING else self.severity=BREAKING_NOT_RESOVABLE endif APPENDIX B OCL CONSTRAINTS 59

B.3 JMI Metamodel Constraints B.3.1 Model Constraints [JM-1] ClassProxyAccessorReturnType context ClassProxyAccessor inv: self.return.type.oclIsTypeOf(JmiClass)

[JM-2] AssociationAccessorReturnType context AssociationAccessor inv: self.return.type.oclIsTypeOf(JmiAssociation)

[JM-3] NestedImportedAccessorReturnType context NestedImportedAccessor inv: self.return.type.oclIsTypeOf(JmiPackage)

[JM-4] LinkExists context LinkExists inv: self.name = "exists" and self.return.type = JmiPrimitiveTypes::Boolean

[JM-5] LinkAdd context LinkAdd inv: self.name = "add" and self.return.type = JmiPrimitiveTypes::Boolean

[JM-6] LinkRemove context LinkRemove inv: self.name = "remove" and self.return.type = JmiPrimitiveTypes::Boolean

[JM-7] AttributeMutatorInputParameter contect AttributeMutator inf: self.input.size < 2 and self.input.at(1).name = "newValue"

B.3.2 Transformation Constraints [TM-1] ClassTransformationInstance Naming conventions for JmiObject elements. context ClassTransformation inv: self.target.packageName = self.source.packageName() and •• helper function [M•15] self.target.className = self.source.substitutedName() •• helper function [M•16]

[TM-2] ClassTransformationInstanceAttributeAccessor For every instance-scoped public attribute, an AttributeAccessor element must be created in the containment of the corresponding JmiObject element context ClassTransformation inv: self.source.contents.select(e|e.oclIsKindOf(Attribute)) •> forAll(attr| (attr.visibility=PUBLIC_VIS and attr.scope=INSTANCE_SCOPED) = self.target.contents •> exists(ja| ja.oclIsKindOf(JmiAttribute) and ja.contents •> exists(acc| acc.oclIsKindOf(AttributeAccessor) and acc.return.type = attr.type.transformation.target and acc.return.multiplicity = attr.multiplicity.toParameterMultiplicity() and acc.name = attr.accessorName() •• helper function [M•13] ) ) ) APPENDIX B OCL CONSTRAINTS 60

[TM-3] ClassTransformationInstanceAttributeMutator For every non-derived, instance-scoped, changeable and single-valued attribute, an AttributeMutator element must be generated in the containment of the corresponding JmiObject element and named according to the JMI naming conventions. context ClassTransformation inv: self.source.contents.select(e|e.oclIsKindOf(Attribute)) •> forAll(attr| (attr.visibility=PUBLIC_VIS and attr.scope=INSTANCE_SCOPED and attr.isChangeable and attr.multiplicity.upper = 1) = self.target.contents •> exists(ja| ja.oclIsKindOf(JmiAttribute) and ja.contents •> exists(mut| mut.oclIsKindOf(AttributeMutator) and mut.input •> at(1).type = attr.type.transformation.target and mut.input •> at(1).multiplicity = attr.multiplicity.toParameterMult() and mut.name = attr.mutatorName() •• helper function [M•14] ) )

[TM-4] ClassTransformationProxy Naming conventions for JmiClass elements. context ClassTransformation inv: self.classProxyTarget.packageName = self.target.packageName and self.classProxyTarget.className = self.target.className + "Class"

[TM-5] ClassTransformationProxyAttributeAccessor For every classifier-scoped public attribute, an AttributeAccessor element must be created in the containment of the corresponding JmiClass element context ClassTransformation inv: self.source.allSuperTypes •> including(self.source) •> collect(contents) •> select(e|e.oclIsKindOf(Attribute)) •> forAll(attr| (attr.visibility=PUBLIC_VIS and attr.scope=CLASSIFIER_SCOPED) = self.classProxyTarget.contents •> exists(ja| ja.oclIsKindOf(JmiAttribute) and ja.contents •> exists(acc| acc.oclIsKindOf(AttributeAccessor) and acc.return.type = attr.type.transformation.target and acc.return.multiplicity = attr.multiplicity.toParameterMultiplicity() and acc.name = attr.accessorName() •• helper function [M•13] ) ) )

[TM-6] ClassTransformationProxyAttributeMutator For every non-derived, classifier-scoped, changeable and single-valued attribute, an AttributeMuta• tor element must be generated in the containment of the corresponding JmiClass element and named according to the JMI naming conventions. context ClassTransformation inv: self.source.contents.select(e|e.oclIsKindOf(Attribute)) •> forAll(attr| (attr.visibility=PUBLIC_VIS and attr.scope=CLASSIFIER_SCOPED and attr.isChangeable and attr.multiplicity.upper = 1) = self.classProxyTarget.contents •> exists(ja| ja.oclIsKindOf(JmiAttribute) and ja.contents •> exists(mut| mut.oclIsKindOf(AttributeMutator) and mut.input•>at(1).type = attr.type.transformation.target and mut.input•>at(1).multiplicity = attr.multiplicity.toParameterMult() and mut.name = attr.mutatorName() •• helper function [M•14] ) ) ) APPENDIX B OCL CONSTRAINTS 61

[TM-7] ClassTransformationElementCreator Every class proxy element must contain a default element creator and a specific element creator that contains all attributes of the class as input parameters. context ClassTransformation inv: self.classProxyTarget.contents •> exists(dc| •• default creator dc.oclIsTypeOf(DefaultCreator) and dc.name = "create" + self.target.name and dc.return.type = self.target) and self.classProxyTarget.contents •> exists(sc| •• specific creator sc.oclIsTypeOf(SpecificCreator) and sc.name = "create" + self.target.name and sc.return.type = self.target and self.source.allSuperTypes() •> including(self.source) •> collect(contents) •> select(a|a.oclIsTypeOf(Attribute) and •• input parameters not a.isDerived and a.scope = INSTANCE_LEVEL) •> forAll(attr| sc.input •> exists(p|p.type = a.type.transformation.target and p.name = a.transformation.target.className) ) )

[TM-8] ClassTransformationStructCreator For every structure type, a creator element must exist. context ClassTransformation let cPrefix = "create" in inv: self.source.contents •> select(s|s.oclIsTypeOf(StructureType)) •> forAll(st| self.classProxyTarget.contents •> exists(sc| sc.name = cPrefix.concat(st.transformation.target.name) and sc.return.type = st.transformation.target and st.contents •> select(sf|sf.oclIsTypeOf(StructureField)) •> forall(f| sc.input •> exists(p| p.name = f.substitutedName() and p.type = f.type.transformation.target) ) ) )

[TM-9] ClassTransformationExtends For JmiObject elements, extends statement must exist for every supertype of the original class; if it has no supertypes, the transformed element has to extend RefObject. context ClassTransformation inv: if (self.source.supertypes.size() = 0) then self.target.extendsStatement.size() = 1 and self.target.extendsStatement •> collect(object) •> contains(JmiReflectPackage::RefObject) else self.source.supertypes •> forAll(s| self.target.extendsStatement •> exists(e| e.object = s.transformation.target) ) endif

[TM-10] PackageTransformation Naming conventions for packages context PackageTransformation inv: self.target.packageName = self.source.packageName() and •• helper function [M•15] self.target.className = self.source.substitutedName().concat("Package") •• [M•16] APPENDIX B OCL CONSTRAINTS 62

[TM-11] PackageTransformationExtends For JmiPackage elements, extends statement must exist for every supertype of the original package; if it has no supertypes, the transformed element has to extend RefPackage. context PackageTransformation inv: if (self.source.supertypes.size() = 0) then self.target.extendsStatement.size() = 1 and self.target.extendsStatement •> collect(package) •> contains(JmiReflectPackage::RefPackage) else self.source.supertypes •> forAll(s| self.target.extendsStatement •> exists(e| e.package = s.transformation.target)) endif

[TM-12] AssociationTransformationLinkExists Type, name and multiplicity of a LinkExists operation must match association end. context AssociationTransformation let end1 = self.source.contents •> select(e|e.oclIsTypeOf(AssociationEnd)) •> at(1) in let end2 = self.source.contents •> select(e|e.oclIsTypeOf(AssociationEnd)) •> at(2) in inv: self.contents.exists(le|le.oclIsTypeOf(LinkExists) and le.input.at(1).name = end1.substitutedName() and le.input.at(1).type = end1.type.transformation.target and le.input.at(1).multiplicity = end1.multiplicity.toParameterMultiplicity() and le.input.at(2).name = end2.substitutedName() and le.input.at(2).type = end2.type.transformation.target and le.input.at(2).multiplicity = end2.multiplicity.toParameterMultiplicity())

[TM-13] AssociationTransformationLinkAdd Type, name and multiplicity of a LinkAdd operation must match association end. Operation only exists if both ends are changeable. context AssociationTransformation let end1 = self.source.contents •> select(e|e.oclIsTypeOf(AssociationEnd)) •> at(1) in let end2 = self.source.contents •> select(e|e.oclIsTypeOf(AssociationEnd)) •> at(2) in inv: (end1.isChangeable and end2.isChangeable) = self.contents.exists(la|la.oclIsTypeOf(LinkAdd) and la.input.at(1).name = end1.substitutedName() and la.input.at(1).type = end1.type.transformation.target and la.input.at(1).multiplicity = end1.multiplicity.toParameterMultiplicity() and la.input.at(2).name = end2.substitutedName() and la.input.at(2).type = end2.type.transformation.target and la.input.at(2).multiplicity = end2.multiplicity.toParameterMultiplicity())

[TM-14] AssociationTransformationLinkRemove Type, name and multiplicity of a LinkRemove operation must match association end. Operation only exists if both ends are changeable. context AssociationTransformation let end1 = self.source.contents •> select(e|e.oclIsTypeOf(AssociationEnd)) •> at(1) in let end2 = self.source.contents •> select(e|e.oclIsTypeOf(AssociationEnd)) •> at(2) in inv: (end1.isChangeable and end2.isChangeable) = self.contents.exists(lr|lr.oclIsTypeOf(LinkRemove) and lr.input.at(1).name = end1.substitutedName() and lr.input.at(1).type = end1.type.transformation.target and lr.input.at(1).multiplicity = end1.multiplicity.toParameterMultiplicity() and lr.input.at(2).name = end2.substitutedName() and lr.input.at(2).type = end2.type.transformation.target and lr.input.at(2).multiplicity = end2.multiplicity.toParameterMultiplicity()) APPENDIX B OCL CONSTRAINTS 63

[TM-15] AssociationTransformationEnd1Accessor Type, name and multiplicity of an End1Accessor operation must match association end. Operation only exists if end is navigable. context AssociationTransformation let end1 = self.source.contents •> select(e|e.oclIsTypeOf(AssociationEnd)) •> at(1) in let end2 = self.source.contents •> select(e|e.oclIsTypeOf(AssociationEnd)) •> at(2) in inv: end1.isNavigable = self.target.contents •> select(a|a.oclIsTypeOf(End1Accessor)) •> exists(acc| acc.name = "get".concat(end1.name) and acc.return.multiplicity = end1.multiplicity.toParameterMultiplicity() and acc.return.type = end1.type.transformation.target and acc.input.size() = 1 and acc.input.contains(p|p.type = end2.type.transformation.target and p.name = end2.type.transformation.target.className) )

[TM-16] AssociationTransformationEnd2Accessor Type, name and multiplicity of an End2Accessor operation must match association end. Operation only exists if end is navigable. context AssociationTransformation let end1 = self.source.contents •> select(e|e.oclIsTypeOf(AssociationEnd)) •> at(1) in let end2 = self.source.contents •> select(e|e.oclIsTypeOf(AssociationEnd)) •> at(2) in inv: end2.isNavigable = self.target.contents •> select(a|a.oclIsTypeOf(End2Accessor)) •> exists(acc| acc.name = "get".concat(end2.name) and acc.return.multiplicity = end1.multiplicity.toParameterMultiplicity() and acc.return.type = end2.type.transformation.target and acc.input.size() = 1 and acc.input.contains(p|p.type = end1.type.transformation.target and p.name = end1.type.transformation.target.className) )

[TM-17] ConstantTransformation Naming conventions, typing and values for constants context ConstantTransformation inv: self.target.name = self.source.substitutedName() and self.target.type = self.source.type.transformation.target and self.target.values = self.source.values APPENDIX B OCL CONSTRAINTS 64

[TM-18] PackageTransformationNestedImportedAccessor For each imported or nested publicly visible package, an accessor must exist with matching name, type and multiplicity. context PackageTransformation inv: self.source.contents.select(i|i.oclIsTypeOf(Import) and i.isClustered = true and i.visibility = PUBLIC_VIS and i.importedNamespace.visibility = PUBLIC_VIS) •> forAll(c| self.target.contents.exists(a| a.oclIsTypeOf(NestedImportedAccessor) and a.name = "get".concat(c.substitutedName()) and a.return.type = c.imported.transformation.target and a.input.isEmpty() ) ) and self.source.contents.select(p|p.oclIsTypeOf(Package) and p.visibility = PUBLIC_VIS •> forAll(n| self.target.contents.exists(a| a.oclIsTypeOf(NestedImportedAccessor) and a.name = "get".concat(n.name) and a.return.type = n.transformation.target and a.input.isEmpty() ) )

[TM-19] PackageTransformationAssociationAccessor For each publicly visible association, an accessor must exist with matching name, type and multiplicity. context PackageTransformation inv: self.source.contents •> select(a|a.oclIsKindOf(Association) and a.visibility = PUBLIC_VIS) •> forAll(p| self.target.contents •> exists(a|a.oclIsTypeOf(AssociationAccessor) and a.name = "get".concat(p.transformation.target.name) and a.return.type = p.transformation.target ) )

[TM-20] PackageTransformationClassProxyAccessor For each publicly visible class proxy, an accessor must exist with matching name, type and multiplicity. context PackageTransformation inv: self.source.contents •> select(c|c.oclIsKindOf(Class) and c.visibility = PUBLIC_VIS) •> forAll(p| self.target.contents •> exists(a|a.oclIsTypeOf(ClassProxyAccessor) and a.name = "get".concat(p.transformation.target.name) and a.return.type = p.transformation.classProxyTarget ) ) APPENDIX B OCL CONSTRAINTS 65

[TM-21] PackageTransformationStructCreator For each publicly visible struct type, an accessor must exist with matching name, type and multiplicity. context PackageTransformation inv: self.source.contents •> select(s|s.oclIsKindOf(StructureType) and s.visibility = PUBLIC_VIS) •> forAll(st| self.target.contents •> exists(sc|sc.oclIsTypeOf(StructCreator) and sc.name = "create".concat(p.transformation.target.name) and sc.return.type = st.transformation.target and st.contents •> select(sf|sf.oclIsTypeOf(StructureField)) •> forall(f| sc.input •> exists(p| p.name = f.name and p.type = f.type.transformation.target) ) ) )

[TM-22] ClassTransformationInstanceReferenceAccessor For every instance-scoped public attribute, an AttributeAccessor element must be created in the containment of the corresponding JmiObject element context ClassTransformation inv: self.source.contents.select(e|e.oclIsKindOf(Reference)) •> forAll(ref| (ref.visibility = PUBLIC_VIS) = self.target.contents •> exists(jr| jr.oclIsKindOf(JmiReference) and jr.contents •> exists(acc| acc.oclIsKindOf(ReferenceAccessor) and acc.return.type = ref.type.transformation.target and acc.return.multiplicity = ref.multiplicity.toParameterMultiplicity() and acc.name = "get".concat(ref.substitutedName()) ) ) )

[TM-23] ClassTransformationInstanceReferenceMutator For every non-derived, instance-scoped, changeable and single-valued attribute, an AttributeMutator element must be generated in the containment of the corresponding JmiObject element and named according to the JMI naming conventions. context ClassTransformation inv: self.source.contents.select(e|e.oclIsKindOf(Reference)) •> forAll(ref| (ref.visibility = PUBLIC_VIS and ref.isChangeable and ref.multiplicity.upper = 1) = self.target.contents •> exists(ja| ja.oclIsKindOf(JmiReference) and ja.contents •> exists(mut| mut.oclIsKindOf(ReferenceMutator) and mut.input •> at(1).type = ref.type.transformation.target and mut.input •> at(1).multiplicity = ref.multiplicity.toParameterMult() and mut.name = "set".concat(ref.substitutedName()) ) ) APPENDIX B OCL CONSTRAINTS 66

[TM-24] ClassTransformationOperation Name, type and multiplicity matching for modeled operations. context ClassTransformation inv: self.source.contents •> select(e|e.oclIsTypeOf(Operation)) •> forAll(o| (o.visibility = PUBLIC_VIS) = self.target.contents •> exists(mo|mo.oclIsTypeOf(ModeledOperation) and o.contents •> select(p|p.oclIsTypeOf(Parameter)) •> forAll(par| if (par.direction = IN_DIR) •• input parameters then mo.input •> exists(ip| ip.type = par.type.transformation.target and ip.name = par.substitutedName() and ip.multiplicity = par.multiplicity.toParameterMultiplicity() ) else mo.return •> exists(op| •• output parameters op.type = par.type.transformation.target and op.multiplicity = par.multiplicity.toParameterMultiplicity() ) endif ) and o.contents •> select(p|p.oclIsTypeOf(Exception)) •> forAll(exc| mo.throws.contains(exc.transformation.target) ) ) )

[TM-25] ClassTransformationException Naming convention for modeled exceptions. context ExceptionTransformation inv: if (self.source.name.endsWith("Exception")) then self.target.name = self.source.substitutedName() else self.target.name = self.source.substitutedName().concat("Exception") endif

[TM-26] ClassTransformationExceptionConstructor context ExceptionTransformation inv: self.source.contents •> select(p|p.oclIsTypeOf(Parameter)) •> forAll(ep|self.target.contents •> exists(c| c.oclIsTypeOf(ExceptionConstructor) and c.input •> contains(jp| jp.name = ep.substitutedName() and jp.type = ep.type.transformation.target and jp.multiplicity = ep.multiplicity.toParameterMultiplicity() ) ) )

[TM-27] ClassTransformationExceptionParameterAccessor context ExceptionTransformation inf: self.source.contents •> select(p|p.oclIsTypeOf(Parameter)) •> forAll(ep|self.target.contents •> exists(a| a.oclIsTypeOf(ParameterAccessor) and p.type = ep.type.transformation.target and p.name = ep.accessorName() ) ) APPENDIX B OCL CONSTRAINTS 67

B.4 Helper Functions [M-1] AllCompositeChildren Definition for a method to recursively calculate all composite children of an element. context ModelElementChange::allCompositeChildren(Classifier c) post: result = AssociationEnd.allInstances() •> select(e|self.newType(e) = c and self.newAggregation(e) = composite) •> iterate(end:AssociationEnd; y:Set(AssociationEnd) = Set{} | y •> including(end.otherEnd()) ) •> collect(type) •> iterate(cl:Classifier; y:Set(Classifier) = Set{} | y •> including(self.allCompositeChildren(cl)) ) •> including(c)

[M-2] NewSuperTypes Determines the set of supertypes for an element after a sequence of changes. context ModelElementChange::newSupertypes(GeneralizableElement element) : Set(GeneralizableElement) post: result = element.supertypes •> including(this.changeSequence.changes •> select(ch| ch.oclIsTypeOf(GeneralizesChange) and ch.subtype = element and ch.kind = ADD) •> collect(supertype) ) •> excluding(this.changeSequence.changes•>select(ch| ch.oclIsTypeOf(GeneralizesChange) and ch.subtype = element and ch.kind = DELETE) •> collect(supertype) )

[M-3] NewSubTypes Determines the set of subtypes for an element after a sequence of changes. context ModelElementChange::newSubtypes(GeneralizableElement element) : Set(GeneralizableElement) post: result = element.suptypes •> including(this.changeSequence.changes •> select(ch| ch.oclIsTypeOf(GeneralizesChange) and ch.supertype = element and ch.kind = ADD) •> collect(subtype) ) •> excluding(this.changeSequence.changes•>select(ch| ch.oclIsTypeOf(GeneralizesChange) and ch.supertype = element and ch.kind = DELETE) •> collect(subtype) )

[M-4] NewContainedElements Determines the set of contained elements after a sequence of changes. context ModelElementChange::newContainedElements(ModelElement element) : Set(ModelElement) post: result = element.containedElements •> including(this.changeSequence.changes •> select(ch| ch.oclIsTypeOf(ContainsChange) and ch.container = element and ch.kind = ADD) •> collect(containedElement)) •> excluding(this.changeSequence.changes •> select(ch|ch.oclIsTypeOf(ContainsChange) and ch.container= element and ch.kind = DELETE) •> collect(containedElement)) APPENDIX B OCL CONSTRAINTS 68

[M-5] NewAssocEnds Determines the set of association ends which have the same type as the element after all changes. 40 context ModelElementChange::newAssocEnds(TypedElement element) : Set(AssociationEnd) post: result = AssociationEnd.allInstances() •> select(ae|ae.type = element) •> including( •• the association ends whose type is changed to element self.changeSequence.changes •> select(ch|ch.oclIsTypeOf(IsOfTypeChange) and ch.type = element) •> collect(typedElement) •> select(t| t.oclIsOfType(AssociationEnd))) •> excluding( •• the association ends whose type is change to another element self.changeSequence.changes •> select(ch|ch.oclIsTypeOf(IsOfTypeChange) and not ch.type = element) •> collect(typedElement) •> select(t| t.oclIsOfType(AssociationEnd) and t.type = element)) •> excluding( •• the deleted association ends self.changeSequence.changes •> select(ch|ch.oclIsTypeOf(ExistenceChange) and ch.kind = DELETE and ch.affectedElement.type = element).collect(affectedElement))

[M-6] Similar Compares two features if they are sufficiently similar to be recognized as the “same” feature. context StructuralFeature::similar(StructuralFeature other) : Boolean post: result = (self.name = other.name and self.type = other.type and self.scope = other.scope and self.visibility = other.visibility and self.multiplicity = other.multiplicity)

[M-7] OldAssocs Determines the set of all associations present in the old version of the metamodel context ChangeSequence::oldAssocs() : Set(Association) post: result = Association.allInstances() •> excluding(self.changes •> select(c | c.oclIsTypeOf(ExistenceChange) and c.kind = add and c.affectedElement.oclIsTypeOf(Association)) •> collect(affectedElement))

[M-8] IsNewElement Checks whether an element was newly added in the course of this change sequence context ChangeSequence::isNewElement(ModelElement element) : Boolean post: result = self.changes •> exists(c | c.oclIsTypeOf(ExistenceChange) and c.kind = ADD and c.affectedElement = element)

[M-9] NewType Determines the new type of a typed element context ChangeSequence::newType(TypedElement element) : Classifier post: if (self.changes •> exists(c | c.oclIsTypeOf(IsOfTypeChange) and c.affectedElement = element)) then result = self.changes •> select(c | c.oclIsTypeOf(IsOfTypeChange) and c.affectedElement = element) •> collect(type) •> last() else result = element.type endif

40Note that the returned set of association ends actually contains the old association ends which still have their old types, and the newly created association ends with the new types. To determine the new type of an association end, use newType(). APPENDIX B OCL CONSTRAINTS 69

[M-10] ToUpper context String::toUpper(character : String): String post: if (character.size() > 1) then result = "" else if (Set{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",} •> contains(character)) then result = character else if (character = "a") then result = "A" else if (character = "b") then result = "B" else if (character = "c") then result = "C" else if (character = "d") then result = "D" else if (character = "e") then result = "E" else if (character = "f") then result = "F" else if (character = "g") then result = "G" else if (character = "h") then result = "H" else if (character = "i") then result = "I" else if (character = "j") then result = "J" else if (character = "k") then result = "K" else if (character = "l") then result = "L" else if (character = "m") then result = "M" else if (character = "n") then result = "N" else if (character = "o") then result = "O" else if (character = "p") then result = "P" else if (character = "q") then result = "Q" else if (character = "r") then result = "R" else if (character = "s") then result = "S" else if (character = "t") then result = "T" else if (character = "u") then result = "U" else if (character = "v") then result = "V" else if (character = "w") then result = "W" else if (character = "x") then result = "X" else if (character = "y") then result = "Y" else if (character = "z") then result = "Z" else result = ""

[M-11] EndsWith context String::endsWith(suffix : String) : boolean post: let len = self.size() in result = (self.substring(self.size()•suffix.size(),self.size()) = suffix)

[M-12] ToParameterMultiplicity context Model::MultiplicityType::toParameterMultiplicity() : ParameterMultiplicity post: if (self.upper < 2) then result = SINGLE else if (self.isOrdered) then result = LIST else result = SET endif endif

[M-13] AccessorNames context Model::Attribute::accessorName() : String let isPrefix = "is" in let getPrefix = "get" in let sname = self.substitutedName() in post: •• for single•valued boolean types, the accessor name starts with "is" if (self.type = PrimitiveTypes::Boolean and self.multiplicity.upper = 1) then if (self.name.substring(1,2) = isPrefix) then result = sname else result = isPrefix.concat(sname.substring(1,1).toUpper()).concat( APPENDIX B OCL CONSTRAINTS 70

sname.substring(2,sname.size())) endif else •• for others, the accessor name starts with "get" result = getPrefix.concat(sname.substring(1,1).toUpper()).concat( sname.substring(2,sname.size())) endif

[M-14] MutatorNames context Model::Attribute::mutatorName() : String let setPrefix = "set" in let sname = self.substitutedName() in post: if (self.type = PrimitiveTypes::Boolean and self.multilicity.upper = 1 and sname.substring(1,2) = isPrefix) then result = setPrefix.concat(sname.substring(3,3).toUpper()).concat( sname.substring(3,sname.size())) else result = setPrefix.concat(sname.substring(1,1).toUpper()).concat( sname.substring(2,sname.size())) ) endif

[M-15] PackagePrefix context Model::ModelElement::packageName() : String post: result = self.contents.select(ppt| ppt.oclIsOfType(Tag) and ppt.tagId = "javax.jmi.packagePrefix") •> collect(values) •> at(1). concat(".").concat(self.outermostPackage().substitutedName())

[M-16] SubstituteName Context Model::ModelElement::substitutedName() : String let substName = (self.source.contents.select(t|t.oclIsKindOf(Tag) and t.tagId = "javax.jmi.substituteName")) in post: if (substName.isEmpty()) then result = self.name else result = substName •> at(1).values •> at(1) endif

[M-17] OutermostPackage Context Model::ModelElement::outermostPackage() : Model::Namespace post: if (self.container.isEmpty()) then result = self else result = self.container.outermostPackage() endif

[M-18] ParameterAccessorNames context Model::Parameter::accessorName() : String let isPrefix = "is" in let getPrefix = "get" in post: •• for single•valued boolean types, the accessor name starts with "is" if (self.type = PrimitiveTypes::Boolean and self.multiplicity.upper = 1) then if (self.name.substring(1,2) = isPrefix) then result = self.name else result = isPrefix.concat(self.name.substring(1,1).toUpper()).concat( self.name.substring(2,self.name.size())) endif else •• for others, the accessor name starts with "get" result = getPrefix.concat(self.name.substring(1,1).toUpper()).concat( self.name.substring(2,self.name.size())) endif APPENDIX B OCL CONSTRAINTS 71

[M-19] NewSuperTypesExtended() context ModelElementChange::newSupertypesExtended(GeneralizableElement element) : Set(GeneralizableElement) post: result = self.newSupertypes(element) •> iterate(i:GeneralizableElement; a:Set(GeneralizableElement) = Set{} | a •> including(i) •> including(self.newSupertypesExtended(i)))

[M-20] NewSubTypesExtended() context ModelElementChange::newSubtypesExtended(GeneralizableElement element) : Set(GeneralizableElement) post: result = self.newSubtypes(element) •> iterate(i:GeneralizableElement; a:Set(GeneralizableElement) = Set{} | a •> including(i) •> including(self.newSubtypesExtended(i)))

[M-21] NewAggregation() contect ModelElementChange::newAggregation(AssociationEnd end) : AggregationKind post: if (self.changeSequence.changes.exists(ac| ac.oclIsKindOf(AggregationKindChange) and ac.affectedElement=end)) then result = self.changeSequence.changes.select(ac| ac.oclIsKindOf(AggregationKindChange) and ac.affectedElement=end) •> collect(aggregation) •> last() else result = end.aggregation endif