=Paper=
{{Paper
|id=Vol-2019/me_4
|storemode=property
|title=Edelta: An Approach for Defining and Applying Reusable Metamodel Refactorings
|pdfUrl=https://ceur-ws.org/Vol-2019/me_4.pdf
|volume=Vol-2019
|authors=Lorenzo Bettini,Davide Di Ruscio,Ludovico Iovino,Alfonso Pierantonio
|dblpUrl=https://dblp.org/rec/conf/models/BettiniRIP17
}}
==Edelta: An Approach for Defining and Applying Reusable Metamodel Refactorings==
Edelta: an approach for defining and applying reusable metamodel refactorings Lorenzo Bettini Davide Di Ruscio Ludovico Iovino DiSIA - University of Florence, Italy DISIM - University of L’Aquila, Italy Gran Sasso Science Institute - L’Aquila, Italy lorenzo.bettini@unifi.it davide.diruscio@univaq.it ludovico.iovino@gssi.it Alfonso Pierantonio DISIM - University of L’Aquila, Italy alfonso.pierantonio@univaq.it Abstract—Metamodels can be considered one of the key to mention debugging. Moreover, the supporting environment artifacts of any model-based project. Similarly to other software allows the developer to estimate and evaluate the impact of artifacts, metamodels are expected to evolve during their life- the refactorings being specified before actually changing the cycle and consequently it is crucial to develop approaches and tools supporting the definition and re-use of metamodel evolving metamodel. refactorings in a disciplined way. The paper is organized as follows: Section II introduces the This paper proposes Edelta, a domain specific language for problem of metamodel refactoring and discusses requirements specifying reusable libraries of metamodel refactorings. The that a metamodel refactoring approach should satisfy. Sec- language allows both atomic and complex changes and it is tion III presents the Edelta language, its implementation, and supported by an Eclipse-based IDE. The developed supporting environment allows the developer to apply refactorings both in the constructs for defining both atomic and complex changes. a batch manner and in a step-by-step fashion, which provides Section IV makes an overview of the features provided the the developers with an immediate view of the evolving Ecore model Eclipse-based IDE supporting the specification and execution before actually changing it. of Edelta specifications. Section V discusses the advantages of the proposed approach with respect to the requirements I. I NTRODUCTION presented in Section II. Related works are discussed in Section Refactoring can be defined as the process of changing a VI. Section VII concludes the paper and outlines some future software system to improve its design, readability, and to plans. reduce bugs [1]. Metamodels play a key role in any model- based approach and, similarly to any software artifact, they are II. M ASTERING M ETAMODEL R EFACTORINGS subject of evolutionary pressures that can arise for several rea- In order to satisfy unforeseen requirements or to better sons. In particular, metamodels can be changed for perfective, represent the considered application domain, metamodels can corrective, preventive and adaptive maintenance goals [2]. be subject to changes as for instance in the case of the simple Metamodel refactorings can be expressed as a sequence of PersonList metamodel shown in Fig. 1.a. The metamodel additions, deletions and changes of elements [3]. Additionally, represents list of persons with the corresponding places where metamodel refactorings can involve also complex operations, they work or live. The metamodel includes the root metaclass which are obtained by mixing atomic changes [4], [5], [6], List that has a containment reference of type Person, [2], [7]. Existing approaches supporting the evolution of which in turn is characterized by the attributes firstname, modeling artifacts are mainly based on tedious and error-prone lastname, and gender. In particular, the gender attribute manual activities [8]. Moreover, the possibility to organize and is specified with an enumeration enabling the specification reuse already defined refactorings is also limited in currently of the literals Male and Female. A person is related to a available approaches [9]. WorkPlace and a LivingPlace, both characterized by In this paper we present a metamodel refactoring approach the attribute address. based on the proposed Edelta domain specific language. Edelta The new version of the metamodel shown in Fig. 1.b has offers the basic mechanisms to express atomic metamodel been modified by means of the following changes: changes i.e., addition, deletion and changes. Moreover, Edelta C1. the attributes firstname and lastname of the meta- provides developers with an extension mechanism enabling the class Person have been merged into the new name use of already developed refactorings, which can be organized attribute; in reusable libraries. The language is endowed with an Eclipse- C2. the metaclass Place has been added as an abstract super based IDE providing features that are typically expected from class of WorkPlace and LivingPlace. Moreover, mature development environments, i.e., syntax highlighting, their address attribute has been pulled-up in the new code completion, error reporting and incremental building, not metaclass; coupled evolution of metamodels and models. Examples of recurrent metamodel refactorings are ExtractSuperClass and IntroduceSubclass [12]. Concrete instances of such refactorings are changes C2 and C3 above, respectively. Operating metamodel refactorings without a dedicated sup- port can be an error-prone task. In particular, there is the need for languages and tools supporting the specification and application of metamodel refactorings in a disciplined way. To this end, by taking inspiration from [15], we defined a set of requirements that a language for specifying reusable metamodel refactorings should implement as presented in the following. a) Conciseness and comprehensibility: Metamodel refactorings should be expressed as concisely and comprehensibly as possible for two main reasons: i) (a) Initial version unnecessarily voluminous code increases development costs and this is particularly the case of metamodel manipulations implemented with GPLs like Java; ii) the quality of the implemented solutions can decrease in case of long specifications since errors might not be easily detected. Contrariwise, if the considered metamodel refactoring language offers adequate constructs for specifying solutions with terms that are closer to the problem at-hand, domain experts can be involved in the development. In this way, the number of bugs and errors introduced with traditional manipulation techniques can be reduced. b) Integration: It should be possible to integrate the metamodel refactoring language with other tools e.g., for dealing with bigger problems like the coupled evolution of metamodels and models. c) Static checks: The language should be statically typed. In the considered context the elements on which refactorings are applied are those of the meta-metamodeling language. Thus, implementing a statically typed DSL in this context means that all references to metaclasses, features of the metaclasses, etc. have to be statically checked by the DSL (b) Evolved version compiler and assignments between such elements have to be checked for type conformance as well. Fig. 1. Evolution of the simple PersonList metamodel d) Refactorings Composability: It is important to support the composition of refactorings into more complex ones. Some of the composing refactorings might depend on other ones and C3. the gender attribute of the metaclass Person has been consequently the supporting tools should be able to analyze replaced by the new sub-classes Male and Female; the specified refactorings to determine which are mutually C4. the reference works of the metaclass Person has been independent, and which refactorings have to be applied se- replaced by the new metaclass WorkingPosition quentially [9]. between the new version of Person and WorkPlace. e) IDE support: Nowadays a DSL should come with a Note that works and persons are still bidirectional supporting tool in order to effectively use the language in in the refactored metamodel, as they used to be in the practice in a productive way. The IDE should integrate all original metamodel. the useful features for the modeled domain, in this case the Even though such changes might appear specific for the refactoring of metamodels. particular metamodel evolution at-hand, modelers might want to define them so to similarly evolve other metamodels in the III. T HE E DELTA L ANGUAGE future. In this respect, by borrowing concepts from object- This section presents Edelta, the domain specific language oriented programming [10] several works [11], [12], [13], we have defined for specifying and applying metamodel [14] have defined catalogs of possible metamodel refactor- refactorings. Edelta provides modelers with constructs for ings with the aim of dealing with specific issues, like the specifying atomic refactoring i.e., additions, deletions and changes, and to define complex reusable metamodel changes Edelta project by properly composing already defined ones. Generated Main Java file Ecore metamodel Ecore evolved metamodel reads produces imports calls compiles to Edelta program uses Java code using Edelta API Edelta imported library Edelta Plugin Fig. 2. A simplified version of the Edelta metamodel An overview of the concepts implemented by the language are shown in Fig. 2. An Edelta specification (represented by the EdeltaModule in the metamodel) can declare operation definitions (which can be reused both by the same program and Fig. 3. Overview of the artifacts involved in Edelta-based metamodel by other Edelta program with the clause use ...as ... as refactorings shown later) and sequences of basic refactoring operations (to add, remove, and change metaclasses and structural features the main file a new metamodel is generated in the modified therein). Such built-in operations are induced by the Ecore folder of the project. metamodel [16] according to the approach defined in [12]. 1 ... In the next section, the Xtext-based implementation of the 2 public static void main(String[] args) throws Exception { Edelta language is presented. Details about how atomic and3 // Create an instance of the generated Java class 4 AbstractEdelta edelta = new Example(); complex refactorings can be specified in Edelta are also given 5 // Make sure you load all the used Ecores in Section III-B and Section III-C, respectively. 6 edelta.loadEcoreFile("model/My.ecore"); 7 // Execute the actual transformations defined in the DSL 8 edelta.execute(); A. Xtext-based implementation of Edelta 9 // Save the modified Ecore model into a new path The Edelta DSL has been implemented with Xtext [17], a 10 11 } edelta.saveModifiedEcores("modified"); popular Eclipse framework for the development of program- Listing 1. Generated main file from Edelta projects ming languages and domain-specific languages. Given a lan- guage grammar definition, Xtext generates the infrastructure The generated Java class (Example in listing 1) extends the for the compiler and a complete IDE support based on Eclipse Edelta Java runtime library base class AbstractEdelta, (e.g., editor with syntax highlighting, code completion, error which provides many methods for configuring reading and reporting and incremental building). writing refactored Ecore models. Figure 3 shows the artifacts that are involved when evolving The Edelta project is available at a metamodel by means of Edelta. The Ecore Metamodel https://github.com/LorenzoBettini/edelta. subject of the evolution is imported in the Edelta program Edelta uses Xbase [18] to provide a rich Java-like syntax being specified. The Edelta program contains all the Edelta for its expressions. In order to make code snippets presented instructions describing the refactorings to be operated by re- in the paper comprehensible, in the following we sketch the using operations already defined in available libraries. When main features of Xbase. Afterwards, the typical structure of the Edelta program is saved and no errors are found by the Edelta programs is discussed. compiler, corresponding Java code is generated for manipulat- 1) Xbase in a nutshell: Xbase is an extensible and reusable ing the input metamodel with the refactorings expressed in the expression language that is completely interoperable with Java Edelta program. The generated Java code uses the Edelta Java and its type system, and is meant to be embedded in an runtime APIs, and it can be called from any Java program. Xtext DSL. Xbase is Java-like, avoiding much of the “syn- The Edelta project wizard creates a Java file with a main that tactic noise” verbosity that is typical of Java. Xbase should calls the generated Java code; this main file, which can be be easily understood by Java programmers. The complete seen as a starting point, is shown in listing 1. When running interoperability with Java implies that our language reuses the Java type system, including generics. All existing Java types Xbase lambda expressions, thanks to all the syntactic sugar can be referred and used from within an Xbase expression, mechanisms just mentioned, allow the programmer to easily that is, all existing Java libraries can be seamlessly reused in write statements and expressions that are compact and more Edelta. This also means that if one has existing refactoring readable than in Java. For instance, assuming the method implementations for Ecore models written in Java, then this newEClass takes a string and a lambda and returns an existing code can be reused in an Edelta program out of the EClass, one can simply write box. This interoperability of Xbase DSLs with Java types 1 newEClass("aclass") [ follows the standard Java classpath mechanisms, meaning that 2 name = "MyEClass" 3] all the Java libraries that are part of the current classpath can be used seamlessly in Edelta programs. Also Edelta reusable instead of refactoring libraries are handled according to the same class- 1 newEClass("aclass", 2 [ e | e.setName("MyEClass") ]) path mechanism. Furthermore, Xbase handles the classpath of standard Eclipse projects, including the Eclipse project created 2) Specifying and compiling Edelta programs: An Edelta by the Edelta project wizard itself. This means that in order to program consists of a bunch of function definitions, which reuse a refactoring library, which can be imported in an Edelta can be reused across Edelta programs (with the clause use program with the clause use ...as ... as shown later, ...as ..., as shown later in the examples), and a list that library must be specified as a dependency of the Eclipse of Ecore refactoring instructions, which represent the actual project; no further custom registries for Java refactorings needs refactoring implemented by the Edelta program. to be implemented. The EPackages that are used in the Edelta program must Terminating semicolons are optional in Xbase. Variable be explicitly specified by their name, using the clauses declarations in Xbase start with val or var, for final and metamodel "..." at the beginning of the Edelta program non final variables, respectively, and do not require to specify (these include both the EPackages under refactoring and the the type if it can be inferred from the initialization expression. EPackages that are simply referred to in the program, e.g., A cast expression in Xbase is written using the infix keyword the Ecore metamodel, typically used to specify data types as. such as EString, EInt, etc.). Content assist is provided by the Xbase extension methods are a syntactic sugar mechanism Edelta editor, proposing all the Ecore files that are available to simulate adding new methods to existing types without in the current project’s classpath (using the standard plug-in modifying them. For example, if m(Entity) is an extension dependencies of Eclipse projects). method, and e is of type Entity, you can write e.m() As mentioned above, the expression syntax of Edelta pro- instead of m(e), even though m is not a method defined in grams is based upon Xbase, thus Edelta provides the same Entity. expressive power of Java, though in a “cleaner” and less Xbase lambda expressions have a sim- verbose way. Besides that, special Edelta expression syntax pler shape than Java lambda expressions: has been introduced to make refactoring easier and statically [ param1, param2, ... | body ]. The types type-checked. of parameters can be omitted if they can be inferred from the Edelta is based on the Java APIs that we implemented as context. When a lambda is the last argument of a method call, part of the Edelta runtime library. These APIs implement the it can be moved out of the parenthesis; for example, instead actual refactoring operations that are applied on an Ecore of writing m(..., [...]), one can write m(...)[...]. model loaded in memory and also take care of saving the Xbase has special syntax for collections: #[e1, ..., changed Ecore model into a new file. The Edelta compiler en] allows the programmer to easily specify a list with initial generates Java code that uses the Edelta runtime Java APIs. contents. Operators such as +, -, +=, -= are available in Note that the generated Java code has no further dependency Xbase also on collections. on the Edelta compiler, nor on the Xtext framework itself: it Xbase provides syntactic sugar for getters and setters: depends only on the Edelta runtime library, which weights only instead of writing o.getName(), one can simply write a few mega bytes. This means that the generated Java code o.name; similarly, instead of writing o.setName("..."), that performs actual refactoring on Ecore files can be executed one can write o.name = "...". independently from Eclipse and the whole Xtext infrastructure. Besides this, Xbase has another additional special vari- Edelta programs refer directly to Ecore model classes, thus able, it. Just like this, which has the same semantics as you do not need to access the Java code generated from in Java, it can be omitted as object receiver of method call an Ecore model. This also means that our approach works and member access expressions. Differently from this, the even in situations where the EMF Java model has not been programmer is allowed to declare any variable or method generated at all (e.g., in those contexts where EMF models are parameter with the name it. Thus, the programmer can created in a completely reflective way). References to Ecore define a custom implicit object receiver in any scope of the elements, such as packages, classes, data types, features and program. Furthermore, when a lambda is expected to have a enumerations, can be specified by their fully qualified name in single parameter, the parameter can be omitted and it will be Edelta using the standard dot notation, or by their simple name automatically available with the name it. if there are no ambiguities (possible ambiguities are checked by the compiler). Such Ecore model references can be used 1 changeEClass. { 2 ... modification block directly from within an Edelta refactoring instruction (such as, 3} createEClass and changeEClass, explained later). On the contrary, when used from within an Xbase expression, they The modification block can be used to modify proper- would conflict with Java type references and fully qualified ties, adding features (with the above mentioned instructions) Java references (e.g., field and method calls). To avoid such or changing existing features (e.g., changeEAttribute, ambiguities, in Edelta Xbase expressions, references to Ecore changeEReference, etc.). model elements are wrapped inside an ecoreref(...) In the initialization and modification blocks, the reference specification1 . to the created or changed Ecore element is automatically avail- In order to show the differences between Java type refer- able through the special variable it, previously explained. To- ences and Ecore model elements in Edelta Xbase expressions gether with the above mentioned syntactic sugar mechanisms we use the following artificial example of variable declara- of Xbase, one can write compact refactoring expressions such tions, where we use both references to the Java types of as the Ecore Java model classes and references to Ecore model 1 createEClass MyNewClass i n mypackage { elements2 : 2 abstract = true // short for it.setAbstract(true) 3} 1 v a l org.eclipse.emf.ecore.EDataType d = e c o r e r e f (ecore. EString) 2 v a l org.eclipse.emf.ecore.EClass c = e c o r e r e f (ecore. One of the main features of Edelta is that it automatically EDataType) keeps track of the refactoring operations that are specified in 3 4 // Type mismatch: cannot convert from EClass to EDataType the program and applies them to an in-memory loaded Ecore 5 v a l org.eclipse.emf.ecore.EDataType d2 = e c o r e r e f (ecore. model. This way, while the developer is editing an Edelta EDataType) refactoring specification, the new and modified elements are Here, org.eclipse.emf.ecore.EDataType is the immediately available and can be used for static type check- reference to the Java interface EDataType defined in ing. For example, let consider the following two refactoring the Java package org.eclipse.emf.ecore, while instructions: ecoreref(ecore.EDataType) is the reference to the 1 createEClass MyNewClass i n mypackage extends AnotherClass { Ecore model element EDataType, defined in the EPackage 2 ... initialization block 3} with name ecore. Everything is statically type-checked in 4 Edelta, according to the Java type system. Thus, the first 5 changeEClass mypackage.AnExistingClass { 6 name = "AnotherClass" two assignments are correct, since the Ecore model element 7 createEReference aNewReference t y p e MyNewClass { ... } EString is a Java EDataType; similarly, the Ecore model 8} element EDataType is a Java EClass. For this reason, the The new EClass extends AnotherClass, which is ac- third assignment is rejected, since the Java interface EClass tually an existing class that is being renamed in the second (i.e., the type of the Ecore model element EDataType) is instruction; the new reference created in the changed EClass not a subtype of the Java interface EDataType. refers to the new EClass created in the first instruction. All B. Built-in metamodel refactoring operations these references are type checked by the Edelta compiler, by Edelta provides a set of basic refactoring operations acting keeping track of the refactorings that are being specified in on EClassifiers and on the features of the EClassifiers. For the program. Note that the generated Java code that performs example, one can introduce a new EClass in the Ecore package the actual refactoring applies the refactorings in such a way that is being refactored with the following instruction: that mutual dependencies do not generate problems. The above described mechanism is implemented by using 1 createEClass i n { 2 ... initialization block the interpreter provided by Xbase. In fact, Xbase provides an 3} interpreter that is able to interpret both the Xbase expressions When creating a new EClass, one can specify also the super- of your DSL programs (even if the corresponding Java code types with the extends clause. In the initialization block one has not been generated yet) and the possible calls to external can set the properties of the newly created EClass and add fea- Java classes (both field accesses and method calls) by Java tures with similar instructions (e.g., createEAttribute, reflection.3 createEReference, etc.). The Edelta compiler invokes the interpreter on a copy, An existing EClass of the package that is being refactored which is kept in memory, of the Ecore files used in the can be modified with the following instruction: Edelta program. The validation and type checking of the Edelta program (which also includes binding references to 1 We could have used a different separator for qualified references to Ecore Ecore elements) is implemented using the Ecore models kept model elements, but the ambiguity would still be there for simple names. Moreover, the use of ecoreref explicit specification allows us to provide in memory, on which the interpretation of the refactorings much better tooling support, especially content assist proposals. 2 Fully qualified names for Java types would not be necessary here, since 3 The DSL implementor has to customize this interpreter concerning the Edelta supports Java-like imports; we use fully qualified names only for the DSL’s specific additional expressions, like, in our case, createEClass, sake of the explanation. changeEClass, etc. is being applied. This allows the compiler to implement the to either increase the timeout or fix the parts that do not following features: terminate. It would be interesting to keep track of the applied • The program can refer to Ecore model elements refactorings and detect these cases; this is the subject of future (EClasses, EStructuralFeatures, etc.) that are created by work. the refactoring operations specified in the program itself. C. Example of Edelta applied to the PersonList metamodel This includes also possible modifications to the Ecore elements. For example, the Edelta compiler’s type check- In this section we show how complex metamodel refac- ing is able to know in a given part of the program if a torings can be specified in Edelta. The metamodel evolution reference has been turned into an attribute or if a feature shown in Fig. 1 is considered throughout the section. has been renamed. Listing 2 shows the specification of all the refactorings • Since the interpretation is applied sequentially on all applied on the initial version of the simple PersonList the refactoring operations, the Edelta compiler is able to metamodel. Line 4 of Listing 2 specifies the package name detect possible errors due to the order of the refactorings, for the evolving metamodel, i.e., PersonList. Line 7 such as, e.g., referring to an Ecore element, in a part of defines the usage of an external Edelta specification called the program, which has been removed by a refactoring refactoringslib, containing all the defined refactorings operation specified before that part of the program. These previously identified in [19]. A fragment of the refactoringslib errors are detected by the compiler, thus the programmer library is shown in Listing 3. has an immediate feedback about the correctness of the At line 9 of Listing 2 the first refactoring is specified refactorings, so that when the actual refactoring performed and the metaclass Person is changed: is applied to actual Ecore models, no bad surprises will introduceSubclasses is called by passing as parameters happen (and the refactored models will still be valid the type of the attribute gender, and the containing class Ecore models). Person (specified using it, which refers to the metaclass • The interpreter will rely on the same Edelta Java APIs currently being refactored). Note the use of ecoreref that are used by the generated Java code. This means (Section II) to access metamodel elements of the EPackages that the semantics of the interpretation will be the same specified by the metamodel clauses at lines 4-5. The as the semantics of the Java code generated by the Edelta definition of the refactoring introduceSubclasses is compiler. Thus, if no validation errors are raised by the in Listing 3: for each literal of the enumeration used as Edelta compiler by relying on the interpretation, then attribute type a new EClass is introduced as subtype of the the Ecore models after the refactorings performed by the containing class, e.g., in the example Male and Female as generated code will still be valid Ecore models (see also subclasses of Person. At the end the attribute is removed the previous item). from the containing class and the EClass becomes abstract. For example, in the previous code snippet, The effect of this first refactoring is shown in fig. 1.b, where AnExistingClass is renamed to AnotherClass the Person metaclass is abstract and it has two subclasses by calling the standard Ecore Java API4 . Since the Edelta Male and Female. compiler interprets on the fly the body of the changeEClass 1 ... 2 package gssi.personexample operation, the AnotherClass can be immediately used in 3 the program (e.g., it is the base class of MyNewClass). Let 4 metamodel "PersonList" 5 metamodel "ecore" us stress that all of this is statically checked.5 6 The interpreter uses a configurable timeout (which defaults 7 use MMrefactorings as refactoringslib 8 to 2 seconds) when interpreting each refactoring Edelta opera- 9 changeEClass PersonList.Person { tion. If the interpretation does not end within the timeout, the 10 refactorings.introduceSubclasses( 11 e c o r e r e f (Person.gender), interpreter is interrupted and a warning is issued by the Edelta 12 e c o r e r e f (Person.gender).EAttributeType as EEnum, compiler (and a corresponding warning marker is put on the 13 i t ); 14 EStructuralFeatures+= Eclipse editor and Problems view). This avoids the interpreter 15 refactorings.mergeAttributes("name", to block the IDE in case of possible endless loops in the 16 e c o r e r e f (Person.firstname).EType, 17 #[ e c o r e r e f (Person.firstname), e c o r e r e f (Person.lastname)] refactoring operations or in case of long running operations6 . 18 ); This way, termination of the interpreter is always guaranteed, 19 } 20 either successfully or with a timeout warning reported on the 21 createEClass Place i n PersonList { operation that caused the timeout. It is then up to the developer 22 abstract = true 23 refactorings.extractSuperclass( i t , 24 #[ e c o r e r e f (LivingPlace.address), e c o r e r e f (WorkPlace. 4 Recall that name = ... is equivalent to it.setName(...) address)]); 5 Further details about the interplay between the interpreter and the compiler 25 } require a deep knowledge of a few advanced mechanisms of the Xtext/Xbase 26 27 createEClass WorkingPosition i n PersonList { framework. For this reason, the full description of the static checks algorithm 28 c r e a t e E A t t r i b u t e description t y p e EString {} will be provided in future works. 29 refactorings.extractMetaClass( i t , 6 In our experience, 2 seconds are more than enough to execute even 30 e c o r e r e f (Person.works),"position","works"); complex refactoring operations on Ecore models. 31 } 32 15 ] 33 changeEClass PersonList.List { 16 f o r (a:attrs){ 34 EStructuralFeatures+= 17 a.EContainingClass.EStructuralFeatures-=a; 35 refactorings.mergeReferences("places", 18 } 36 e c o r e r e f (Place), 19 r e t u r n newAttr; 37 #[ e c o r e r e f (List.wplaces), e c o r e r e f (List.lplaces)] 20 } 38 ); 21 ... 39 } 22 d e f mergeReferences(String newAttrName, EClassifier etype, Listing 2. Snippet of the Edelta program for PersonList metamodel example List refs): EReference{ 23 v a l newRef=newEReference(newAttrName)[ 24 EType=etype; Line 14 of Listing 2 enriches the structural features of 25 ] Person with the result of the mergeAttributes refac- 26 f o r (r:refs){ 27 r.EContainingClass.EStructuralFeatures-=r; toring defined in Listing 3. Such a refactoring is responsible 28 } of merging a list of attributes into a single one, if they have 29 r e t u r n newRef; 30 } the same type. In this example the attributes firstname and 31 ... lastname are merged into the new one name. 32 d e f extractSuperclass(EClass superclass, List attrs){ The refactorings specified at lines 21-25 of Listing 2 are 33 v a l extracted_attr=attrs.head; responsible of the extraction of a superclass Place from the 34 f o r (attr: attrs){ 35 attr.EContainingClass.ESuperTypes+=superclass; attributes address of LivingPlace and WorkPlace, by 36 attr.EContainingClass.EStructuralFeatures-=attr calling extractSuperclass, defined in Listing 3. This 37 } 38 superclass.EStructuralFeatures+=extracted_attr; refactoring is called when there are two metaclasses with 39 } similar features: a new super-metaclass is created and the 40 ... 41 d e f extractMetaClass(EClass extracted_class, EReference f, common features are moved to the superclass [10]. The newly String _in, String _out) : v o i d { created metaclass Place is passed as implicit parameter 42 v a l ref_in=newEReference(_in)[ 43 EType=extracted_class; it to the method definition call at line 23. The effect of 44 lowerBound=f.EOpposite.lowerBound; this refactoring is shown in Fig. 1.b, where a new abstract 45 upperBound=1; 46 ]; metaclass Place is introduced and the address attribute is 47 v a l old_ref=newEReference(f.name)[ moved up in the hierarchy. 48 lowerBound=1; 49 upperBound=1; Line 29 of Listing 2 invokes the extract metaclass refactor- 50 EType=f.EType; ing on a newly created metaclass WorkingPosition. This 51 EOpposite=ref_in; 52 ]; refactoring creates a new metaclass representing a feature of 53 extracted_class.EStructuralFeatures+=old_ref; the owner metaclass. In the example the reference works 54 ref_in.EOpposite=old_ref; 55 f.EOpposite.lowerBound=1; is a simple association between the metaclass Person and 56 f.EOpposite.upperBound=1; the WorkPlace. We also pass as parameters the in and 57 extracted_class.EStructuralFeatures+=f.EOpposite; 58 f.EReferenceType.EStructuralFeatures+=ref_in; out references from and to this new metaclass from the old 59 f.EType=extracted_class; one (in this example, position and works, respectively). 60 f.containment=true; 61 f.name=_out; The result of this refactoring is shown in Fig. 1.b where the 62 } WorkingPosition metaclass is linked to Workplace and 63 ... Person with the references position and works. A new Listing 3. Fragment of the existing refactoringlib library attribute description of the job position that will be used to characterize the person, is also created at line 28. It is worth noting that the same refactoring example can Since the metaclass List has two different references for be applied to other metamodels presenting the same structural the metaclasses LivingPlace and WorkPlace, having elements, obtaining the same improvements of this running now a common superclass, they can be merged into a single example. This is possible thanks to the reusable common reference having the same common supertype. This is the case refactoring definitions that can be used in Edelta. of the mergeReferences refactoring specified at lines 33- IV. T HE E DELTA EDITOR 38 of Listing 2. 1 ... The Edelta editor provides typical Eclipse tooling mecha- 2 d e f introduceSubclasses(EAttribute attr,EEnum attr_type, nisms, including content assist and navigation to definitions. EClass containingclass){ 3 containingclass.abstract = true; This is implemented both for Java types and for Ecore model 4 f o r (subc : attr_type.ELiterals){ elements. For example, in Fig. 4 we show the content assist 5 containingclass.EPackage.EClassifiers+=newEClass(subc. literal)[ for references to EClasses of the imported Ecore models. Nav- 6 ESuperTypes+=containingclass; igating to such an element automatically opens the standard 7 ]; 8 containingclass.EStructuralFeatures-=attr; EMF Ecore tree editor. 9 } Besides allowing our compiler to perform static type check- 10 } 11 ... ing, keeping the in-memory Ecore model continuously updated 12 d e f mergeAttributes(String newAttrName, EClassifier etype, by interpreting the specified refactoring operations also allows List attrs): EAttribute{ 13 v a l newAttr=newEAttribute(newAttrName)[ us to provide the developer with a immediate view of the 14 EType=etype; modified Ecore model in the Outline view. This is shown in Fig. 4. Content assist for Ecore model elements. Fig. 6. Evolution result of the interpretation of the Edelta program in the Outline view . a) Conciseness and comprehensibility: If we compare the Edelta specification of the running example with the generated Edelta Java code in terms of lines of code, the result would be 42 vs 225 (81+144). We only considered the Edelta program since the refactoring library is defined once and then imported in the Edelta program. The mechanism of importing already defined refactorings increases the understandability of the Edelta program if we compare this with reading the full Java code. At the same level a comparison with other model transformation frameworks used as a metamodel refactoring Fig. 5. The Edelta DSL editor, showing the synchronized Outline with mechanism can be proposed and will be part of future plans. the Ecore model being refactored and the original Ecore model that can be b) Integration: An important application of this require- navigated from the Edelta DSL editor. ment concerns the integration of the proposed approach with tools supporting the coupled evolution of metamodels and Fig. 5: in the program we created a new EClass and a new models. We designed Edelta in order to enable its integration EAttribute and this is immediately reflected in the Outline with EMFMigrate [20]. Edelta will be used to specify the pat- view. New elements created by the refactoring operations terns that have to be matched to trigger model migrations [21]. and elements modified by the refactoring operations are also c) Static checks: The proposed language refers to actual immediately available in the content assist. By referring to the meta-elements of the Ecore metamodel. This means that Edelta running example, the Outline view shown in Fig. 6 represents is able to catch possible refactoring errors at compilation the modified metamodel, which is computed by the Edelta time, so that the generated Java code implementing the actual compiler on-the-fly through the interpretation of the Edelta refactor will not misbehave when executed on the Ecore model specification given in Listing 2. being refactored. In order to reduce possible problems when Finally, one of the advantages of using Xbase is that Edelta executing the generated Java code, the Edelta compiler also specifications can be directly debugged in Eclipse: when performs an on-the-fly interpretation of the refactoring and running the generated Java code in the Eclipse debugger, the uses such information to perform further static checks. original Edelta source code can be debugged (all the standard d) Refactorings Composability: Such a requirement is Eclipse debugging features are available, i.e., variables view satisfied by the possibility of defining reusable refactoring li- and breakpoints). braries that can be included when specifying Edelta programs. e) IDE support: Edelta is distributed with a complete V. D ISCUSSION Eclipse IDE tooling support, as shown in Section IV, by making the metamodel refactoring a supported methodology In this section we will stress the advantages of having a with all the related features. metamodel refactoring tool instead of using traditional code based techniques, e.g., Java code for metamodel evolution. In VI. R ELATED W ORK the following we briefly recall the requirements identified in The analysis of the existing refactoring tool made in [9] Section II and discuss how the proposed approach addresses highlights that there are still a lot of open issues that remain to them. be solved. They conclude that there is the need for formalisms, processes, methods and tools that address refactoring in a more Metamodel for specifying atomic operations specification with consistent, generic, scalable and flexible way. In [22] authors a related classification. A metamodel change is seen as a explored the concept of model refactoring using a UML class transformation of one version of a metamodel to another. The diagram as metamodel. Some concrete experiments have been changes are then classified by their impact on the compatibility used to show how graph transformations can be used to support to existing model data and this classification is formalized model refactoring. The proposed approach is implemented in using OCL constraints. The metamodel presented in that the Fijaba tool. This paper shows in concrete experiments paper is quite similar to the Edelta metamodel, even if the how graph transformation technology can be used to support implementation is not cited in [3]. The derived classification model refactoring. A refactoring plug-in can be developed can be in the future included in Edelta with the intent to to refactor UML class diagrams, where each refactoring is estimate the impact of metamodel refactorings on existing expressed as a graph production. The similarity with the artifacts, as we already proposed in [26]. presented approach is based on the fact that class diagrams The Wodel domain specific language is presented in [27] are customary used as simplified representation for metamodel with the intent of facilitating the specification and creation languages. The approach in [22] uses graph transformations to of model mutations by means of a meta-model independent apply the refactoring and in Edelta the refactoring is directly approach. The language offers primitives for model mutations translated into Java code. Model refactoring, with a very (e.g., creation, deletion, reference reversal), item selection similar intent, is also explored in [23], where an Eclipse strategies, and composition of mutations. As in Edelta, Wodel incubation project providing specification and application of specifications are compiled into Java, and can be extended refactorings on models is proposed. with post-processor steps for particular applications. The dif- In [24] refactoring is described as one of the most important ferences with Edelta are in the abstraction layers in which and commonly used techniques of transforming a piece of the refactoring / mutation is applied, but Edelta can be easily software in order to improve its quality. They analyzed source adapted and extended in order to support also instances code version control system logs of popular open source refactorings, and this is part of the future plans. software systems to detect changes marked as refactorings and examine how the software metrics are affected by this process, VII. C ONCLUSIONS in order to evaluate whether refactoring is effectively used as a means to improve software quality. This kind of applications In Model Driven Engineering metamodels play a key role are possible future improvements that can be introduced with since they underpin the definition of different kinds of artifacts the complete Edelta environment, since the refactoring can including models, transformations, and code generators. Simi- be simulated in order to understand if metamodeling quality larly to any kind of software artifacts, metamodels can evolve attributes can be improved applying it. under evolutionary pressure that arises when clients and users In [4] authors developed an approach to automate the detec- express the need for enhancements. Metamodel refactorings tion of source code refactorings using structural information are typically operated in ad-hoc manners and by means of extracted from the source code. This approach takes as input manual and error-prone editing processes. a list of possible refactorings as an external library, a set of In this paper we proposed Edelta, a domain specific lan- structural metrics and the initial and revised versions of the guage for specifying and applying reusable metamodel refac- source code. It generates as output a sequence of detected torings. The language allows the developer to specify both changes expressed as refactorings. This refactoring sequence atomic and complex changes. The implementation of Edelta is determined by a search-based process that minimizes the is based on Xtext and the language is endowed with an metrics variation between the revised version of the software Eclipse-based development environment providing also early and the version yielded by the application of the refactoring evaluation of the refactoring being applied. As future work we sequence to the initial version of the software. This work is plan to extend the language and the supporting environment by very close to our final aim, i.e., use the language we presented introducing the notion of quality models. Essentially, modelers as automatic refactorings detection and application, where will have the possibility to assess the refactoring impact on the metrics calculation returns an improvement in metamodel quality attributes that might be defined and associated to the quality [25]. metamodel being changed. Concerning the catalog of refactorings in object oriented programming presented by Fowler [10] there is a strong R EFERENCES correlation with the library of refactoring we defined by using [1] K. O. Elish and M. Alshayeb, “A classification of refactoring methods the proposed Edelta language. For the running example in based on software quality attributes,” Arabian Journal for Science section III-C a library of reusable metamodel refactorings has and Engineering, vol. 36, no. 7, pp. 1253–1267, Nov 2011. [Online]. Available: http://dx.doi.org/10.1007/s13369-011-0117-x been implemented following the definitions in http://www. [2] M. Herrmannsdoerfer, “COPE - A workbench for the coupled evolu- metamodelrefactoring.org/. The proposed metamodel refactor- tion of metamodels and models,” Lecture Notes in Computer Science ing catalog presents many similarities with the one maintained (including subseries Lecture Notes in Artificial Intelligence and Lecture Notes in Bioinformatics), vol. 6563 LNCS, pp. 286–295, 2011. by Fowler for the reasons already exposed above. [3] E. Burger and B. Gruschko, “A Change Metamodel for the Evolution of The work in [3] presents a metamodel called Change MOF-Based Metamodels.” Modellierung, vol. 161, pp. 285–300, 2010. [4] R. Mahouachi, M. Kessentini, and M. Ó. Cinnéide, Search-Based the 6th International Workshop on Modeling in Software Engineering, Refactoring Detection Using Software Metrics Variation. Berlin, ser. MiSE 2014. New York, NY, USA: ACM, 2014, pp. 55–60. Heidelberg: Springer Berlin Heidelberg, 2013, pp. 126–140. [Online]. [Online]. Available: http://doi.acm.org/10.1145/2593770.2593774 Available: http://dx.doi.org/10.1007/978-3-642-39742-4 11 [26] L. Iovino, A. Pierantonio, and I. Malavolta, “On the Impact Significance [5] L. M. Rose, D. S. Kolovos, R. F. Paige, F. A. C. Polack, and S. Poulding, of Metamodel Evolution in MDE,” JoT, vol. 11, no. 3, pp. 3:1–33, Oct. “Epsilon Flock: a model migration language,” Software and Systems 2012. Modeling, pp. 1–21, 2012. [27] P. Gómez-abajo, E. Guerra, J. D. Lara, P. Gomeza, and E. Guerra, [6] B. Gruschko, “Towards synchronizing models with evolving metamod- “Wodel : A Domain-Specific Language for Model Mutation,” pp. 1– els,” in In Proc. Int. Workshop on Model-Driven Software Evolution held 6, 2016. with the ECSMR, 2007. [7] A. Narayanan, T. Levendovszky, D. Balasubramanian, and G. Karsai, “Automatic domain model migration to manage metamodel evolution,” Lecture Notes in Computer Science (including subseries Lecture Notes in Artificial Intelligence and Lecture Notes in Bioinformatics), vol. 5795 LNCS, pp. 706–711, 2009. [8] B. Meyers and H. Vangheluwe, “A framework for evolution of modelling languages,” Science of Computer Programming, vol. 76, no. 12, pp. 1223–1246, 2011. [Online]. Available: http://dx.doi.org/10. 1016/j.scico.2011.01.002 [9] T. Mens, S. Demeyer, B. D. Bois, H. Stenten, and P. V. Gorp, “Refactoring: Current research and future trends,” Electronic Notes in Theoretical Computer Science, vol. 82, no. 3, pp. 483 – 499, 2003. [Online]. Available: http://www.sciencedirect.com/science/article/ pii/S1571066105826246 [10] M. Fowler, K. Beck, J. Brant, W. Opdyke, and D. Roberts, Refactoring: improving the design of existing code. Addison-Wesley, 1999. [11] M. Herrmannsdoerfer, S. Benz, and E. Juergens, “Cope - automating coupled evolution of metamodels and models,” in Proceedings of the 23rd European Conference on ECOOP 2009 — Object- Oriented Programming, ser. Genoa. Berlin, Heidelberg: Springer- Verlag, 2009, pp. 52–76. [Online]. Available: http://dx.doi.org/10.1007/ 978-3-642-03013-0 4 [12] A. Cicchetti, D. Di Ruscio, R. Eramo, and A. Pierantonio, “Automating co-evolution in model-driven engineering,” in 12th International IEEE ECOC 2008, 15-19 September 2008, Munich, Germany. IEEE Com- puter Society, 2008, pp. 222–231. [13] A. Cicchetti, D. Di Ruscio, and A. Pierantonio, “Managing Dependent Changes in Coupled Evolution,” in ICMT, ser. LNCS. Springer, 2009, vol. 5563, pp. 35–51. [14] D. Di Ruscio, L. Iovino, and A. Pierantonio, “Evolutionary Together- ness: How to Manage Coupled Evolution in Metamodeling Ecosystems,” in ICGT, vol. 7562. Springer, 2012, pp. 20–37. [15] B. G. Humm and R. S. Engelschall, “Language-oriented programming via dsl stacking,” in Proceedings of the 5th International Conference on Software and Data Technologies, 2010, pp. 279–287. [16] D. Steinberg, F. Budinsky, M. Paternostro, and E. Merks, EMF: Eclipse Modeling Framework 2.0, 2nd ed. Addison-Wesley Professional, 2009. [17] L. Bettini, Implementing Domain-Specific Languages with Xtext and Xtend, 2nd ed. Packt Publishing, 2016. [18] S. Efftinge, M. Eysholdt, J. Köhnlein, S. Zarnekow, W. Hasselbring, and R. von Massow, “Xbase: Implementing Domain-Specific Languages for Java,” in GPCE. ACM, 2012, pp. 112–121. [19] M. D. Univaq, “Metamodel refactorings catalog,” http://www. metamodelrefactoring.org, 2011, accessed: 2016-09-30. [20] D. Di Ruscio, L. Iovino, and A. Pierantonio, “What is needed for managing co-evolution in mde?” in Proceedings of the 2nd IWMCP’11. ACM, 2011, pp. 30–38. [21] D. Wagelaar, L. Iovino, D. Di Ruscio, and A. Pierantonio, “Translational semantics of a co-evolution specific language with the EMF transforma- tion virtual machine,” in ICMT, ser. LNCS. Springer, 2012, vol. 7303, pp. 192–207. [22] T. Mens, On the Use of Graph Transformations for Model Refactoring. Berlin, Heidelberg: Springer Berlin Heidelberg, 2006, pp. 219–257. [Online]. Available: http://dx.doi.org/10.1007/11877028 7 [23] T. Arendt, F. Mantz, and G. Taentzer, “Emf refactor: specification and application of model refactorings within the eclipse modeling framework,” in Proceedings of the BENEVOL workshop, 2010. [24] K. Stroggylos and D. Spinellis, “Refactoring–does it improve software quality?” in Proceedings of the 5th International Workshop on Software Quality, ser. WoSQ ’07. Washington, DC, USA: IEEE Computer Society, 2007, pp. 10–. [Online]. Available: http: //dx.doi.org/10.1109/WOSQ.2007.11 [25] J. Di Rocco, D. Di Ruscio, L. Iovino, and A. Pierantonio, “Mining metrics for understanding metamodel characteristics,” in Proceedings of