Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Refactor
EMF Refactor
EMF Refactor is an Eclipse open source tool environment conveniently supporting a structured model quality assurance process. In particular, EMF Refactor supports metrics reporting, smell detection, and refactoring for models being based on the Eclipse Modeling Framework, a widely used open source technology in model-based software development.
The following major functionalities are provided:
- User-friendly support for project-specific configurations of model metrics, smells, and refactorings.
- Calculation of model metrics, detection of model smells, and application of model refactorings.
- Generation of model metrics and smell detection reports.
- Suggestion of suitable refactorings in case of specific smell occurrences.
- Provision of suitable information in cases where new model smells come in by applying a certain refactoring.
- Support for the implementation of new model metrics, smells, and refactorings.
The tool environment mainly consists of two kinds of modules: For calculating model metrics, detecting smells, and executing refactorings there is an application module each. Similarly there are three specification modules for generating metrics, smell, and refactoring plugins containing Java code that can be used by the corresponding application module. Details on the design of EMF Refactor can be found here: EMF Refactor Architecture. Lists of provided techniques can be found here: Techniques.
Example Applications
In the following, the application of several model quality assurance techniques supported by EMF Refactor is presented. We demonstrate this application on a UML class model representing the domain of a vehicle rental company.
Example UML class model
The following figure shows a first UML example model that has been developed in an early stage during the development of an accounting and customer management system for a vehicle rental company. This first version of the domain model of the company is shown as UML class diagram modeled using the EMF-based UML CASE tool Papyrus [3].
The model consists of altogether four packages:
- Package Commonalities contains general concepts (enumerations, interfaces, and common classes like Person and Date).
- Package RentalCompany contains the main entities of the company (represented by class VehicleRental). The company has a number of employees and customers. Each customer is associated with a concrete employee (see association end consultant). Special persons are subcontractors of the company which represent both, a customer and an employee. The right-hand-side of this package shows that the company owns several cars, trucks, and motorbikes which can be rented by some customer.
- Packages Services and Invoicing contain classes for renting a vehicle by some customer as well as for billing purposes.
How to calculate model metrics
For the first overview on a model, a report on project-specific model metrics might be helpful. In the following, we calculate common metrics to get an overview on interesting model properties.
To calculate relevant metrics only, our tool environment supports a project-specific configuration for the metrics suite. The configuration is managed by means of a dedicated project properties page (select project -> menu Project -> Properties -> category EMF Quality Assurance -> subcategory Metrics Configuration). On this page, all existing model metrics for EMF-based models are listed. They are structured with respect to the corresponding meta-model (e.g., UML and Ecore) and to the corresponding element type the metrics are calculated on (the context).The following figure shows the project-specific configuration page for our example project.
On this page, all existing model metrics for EMF-based models are listed. They are structured with respect to the corresponding meta model (e.g., UML and Ecore) and to the corresponding element type the metrics are calculated on (the context). In the figure above, we activate model metrics for UML packages concerning abstractness (A, NACP, NCCP, and TNCP) and coupling issues (Ca, Ce, I, and TC).
The calculation of metrics on a specific model element is started from its context menu (menu EMF Quality Assurance (use existing techniques) -> Calculate Configured Metrics (on element)). In our UML show case, this element is selected from within the graphical GMF-based Papyrus editor. However, EMF Refactor also supports further editors like the tree-based EMF instance editor and textual editors generated by Xtext [4]. The following figure shows the calculated results of the configured UML metrics on packages Commonalities and RentalCompany from the example UML class model above.
The results view shows that package Commonalities contains altogether four classes (metric TNCP): two concrete and two abstract classes (metrics NCCP and NACP). Furthermore, metric Ca (afferent coupling: number of classes in other packages depending on classes of the package) of package RentalCompany is evaluated to 3 whereas its efferent coupling metric (number of classes within the package depending on classes in other packages - Ce) is evaluated to 7. Metrics A, TC, and I are calculated using these ’basic’ metrics. The abstractness (A) of package Commonalities is 0.5 (ratio between the number of abstract classes in the package and the total number of classes in the package). The total coupling (TC: afferent + efferent coupling) of package RentalCompany is 10 and its instability (I) is 0.7 (ratio between efferent coupling and total coupling).
EMF Refactor’s metrics tool provides the export of calculated results for reporting purposes (select top down menu of the results view -> Export Results). The following output formats are supported: XML (default), HTML, PDF, Postscript, MS DOC, MS PPT, MS XLS, ODP, ODS, and ODT. Furthermore, several output designs are provided but also custom designs can be imported. The following figure shows two PDF exports of our example metrics calculation.
On the left-hand side, metric values for Ca (Afferent Coupling) and Ce (Efferent Coupling) of package RentalCompany are compared using a pie diagram. The right-hand side shows an exported tube diagram containing the metric values for Ca, Ce, and TC (Total Coupling).
How to detect model smells
The discussion of metrics results shows that a manual interpretation of metric values seems to be unsatisfactory and error-prone. So, another static model analysis technique is required, more precisely an automatic detection of model smells. As for model metrics, EMF Refactor provides a configuration of specific model smells that are relevant for the current project (select project -> menu Project -> Properties -> category EMF Quality Assurance -> subcategory Smells Configuration). The following figure shows the configuration dialog listing all system-known model smells with respect to their meta model. For a metric-based model smell, a corresponding threshold can be configured.
In this dialog, two metric-based smells are activated. Smell Abstract Package occurs if the value of metric A (Abstractness: ratio between the number of abstract classes in the package and the total number of classes in the package; see previous section) is higher than 0.7. The second metric-based smell, Large Class, relies on metric NFEAC (number of owned features of the class) and comparator > (greater than). We set the limit for smell Large Class to 7.0, i.e., this smell occurs if a class owns more than seven attributes or operations.
Similar to the calculation process for model metrics, a smell analysis can be triggered either for the entire model or for a concrete model element (menu EMF Quality Assurance (use existing techniques) -> Find Configured Model Smells). In the latter case, all smells are reported occurring within the containment hierarchy of the selected model element. Nevertheless, it has to be considered that there are model smells which might be distributed along several subtrees (like Equally Named Classes, looking for classes in different packages having the same name). However, EMF Refactor provides smell analysis on subtrees only in order to narrow the scope of the analysis, for example on large-scale models.
Analyzing the example UML class model above, the smell detection analysis discovers the existence of altogether 19 concrete smells according to this configuration. The left-hand side of the following figure shows the results of this analysis in a dedicated results view.
The report shows that smell Equal Attributes in Sibling Classes occurs 13 times. Example occurrences are attributes Motorbike::power, Car::manufacturer, and Customer::id. Six kinds of model smells occur once each, for example smell Speculative Generality Interface looking for an interface that is realized by one single class only. Here, the involved elements are interface Rentable and class Vehicle.
Concerning concrete smell occurrences, the smell detection tool in EMF Refactor provides a highlighting mechanism for involved model elements within the standard tree-based EMF instance editor, graphical GMF editors, and textual Xtext editors. For example, selecting the occurrence of smell Speculative Generality Interface in the smell view (see left-hand side of the figure above) highlights interface Rentable, class Vehicle, and the realization relation between them within the graphical Papyrus editor as shown in the right-hand side of the figure.
The next step during a model review is to interpret the results of the smell detection analysis. Potential reactions on detected smells are (note that not each smell should be eliminated):
- Use refactoring Pull Up Attribute on attributes manufacturer, power, and regnumber from classes Car, Motorbike, and Truck to the common parent class Vehicle.
- Smell Speculative Generality Class should be removed by using refactoring Remove Superclass on class Service since the company does not offer further services.
- Rename classes RentalCompany::VehicleRental to VehicleRentalCompany and Services::VehicleRental to VehicleRentalService.
- Class Invoice is unused up to now. There should be an attribute named invoices in class VehicleRentalCompany with type Invoice and multiplicity 0..*.
How to apply model refactorings
Besides manual changes, model refactoring is the technique of choice to eliminate occurring smells. This task is provided by the primary functionality of EMF Refactor. Again, this component provides a configuration mechanism to select refactorings being relevant for the given modeling project. The configuration user interface is similar to that of the metrics component and is not shown here.
There are two alternative ways to trigger a model refactoring in EMF Refactor: First, a refactoring can be invoked from within the context menu of at least one model element in the standard tree-based EMF instance editor, the graphical GMF-based editor, or the textual Xtext editor (menu EMF Model Refactorings). Depending on the selected element(s), only those refactorings are provided in the menu being defined for the corresponding model element type(s). For example, UML refactoring Extract Superclass is provided only after selecting at least two classes. The second way to trigger a model refactoring is to use the quick fix mechanism of the smell results view as shown on the left-hand side of the figure above (menu Suggest Refactorings). Starting from this view, EMF Refactor provides a suggestion for potential refactorings according to pre-defined smell-refactoring relations and a dynamic analysis of applicable model refactorings.
The suggestion dialog is started from within the context menu of a smell occurrence (e.g., occurrence {Motorbike, power} of smell Equal Attributes in Sibling Classes) and consists of three tabs. The first tab (see top of the figure above) suggests all model refactorings that have been manually defined as being suitable to erase the corresponding model smell. The second tab (see middle of the figure above) lists all those model refactorings which have been proven to be applicable on at least one model element in the selected smell occurrence. Please note that this does not necessarily mean that each presented refactoring would improve the model quality by erasing a model smell. It simply means that the target model structure allows the application of that refactoring. For example, refactoring Rename Class obviously does not influence the afore mentioned smell. The third tab (see bottom of the figure above) combines the manually defined solution and the actually applicable solutions. Finally, each tab informs about possible new smells potentially inserted when applying the refactoring (according to the manual configuration).
After invoking a refactoring, either from within an editor or by the provided quick fix mechanism, refactoring-specific basic conditions are checked (initial precondition check) according to the refactoring workflow provided by the Language Toolkit (LTK) [5]. Then, the user has to set all needed parameters. The following figure shows the parameter input dialog for refactoring Pull Up Attribute that is invoked on attribute power of class Motorbike. Due to multiple inheritance in UML, the superclass to which the attribute should be moved must be set.
Then, EMF Refactor checks whether the user input does not violate further conditions (final precondition check). In case of erroneous parameter input a detailed error message is shown. If the final check has passed, a preview of model changes to be performed by the refactoring is provided using EMF Compare [6].
Besides the model change preview, EMF Refactor provides the opportunity to get a quantitative analysis on changes of smell occurrences. In contrast to the manual configuration of potential refactoring-smell-relations, this analysis provides the modeler with the total number of occurrences of model smells before and after a potential application of a given model refactoring. It thereby helps with the decision whether or not a refactoring application would improve the overall model quality or would it even make worse. The following figure shows the information dialog when applying UML refactoring Pull Up Attribute on attribute Motorbike::power.
Before the refactoring, UML model smell Equal Attributes in Sibling Classes occurs 13 times; after the refactoring three occurrences would be eliminated (since attribute power is pulled up from each subclass of Vehicle, i.e., classes Motorbike, Car, and Truck). Moreover, no further smell would be inserted. However, 10 occurrences of smell Equal Attributes in Sibling Classes as well as the single occurrences of smells Large Class, Equally Named Classes, Speculative Generality Class, Diamond Inheritance, Unused Class, and Speculative Generality Interface would remain. Finally, all model changes can be committed and the refactoring is performed.
The following figure shows the example UML class model after performing several model changes, being refactorings and manual changes, as described above. Now, class Vehicle owns the afore redundant attributes manufacturer, power, and regnumber. Class Service has been removed so that VehicleRentalService (formerly named VehicleRental) is the only offered service left. Finally, the main class VehicleRentalCompany (also formerly named VehicleRental) has a new attribute invoices with type Invoice and multiplicity 0..*.
From the detected smells seven occurrences are left. However, there are model parts remaining suspicious with respect to several model quality aspects. For example, there are associations from class Company to classes Car, Truck and Motorbike hinting to some kind of redundant modeling. This shows that project-specific model quality assurance techniques need not be completely defined (and implemented) before a project starts. The quality assurance process should be refined during the model development phase in order to be steadily improved. For example UML model smell Association Clumps as well as refactoring Pull Up Association would extend the suite of project-specific model quality assurance techniques in a meaningful way. How the specification of new model assurance techniques is supported by EMF Refactor is shown in the following.
Example Specifications
EMF Refactor provides a wizard-based specification process for each supported quality assurance technique. In the following, several concrete specification mechanisms for model quality assurance techniques are presented. The techniques and mechanisms are discussed along a domain-specific modeling language for defining web applications.
Example DSML
To demonstrate the specification facilities provided by EMF Refactor, we use a domain-specific modeling language (DSML) called Simple Web Model (SWM) for defining a specific kind of web applications. In this example case, we assume the following scenario (taken from [1]):
A software development company is repeatedly building simple web applications being mostly used to populate and manage persistent data in a database. Here, a typical three-layered architecture following the Model-View-Controller (MVC) pattern [2] is used. As implementation technologies, a relational database for persisting the data as well as plain Java classes for retrieving and modifying the data are employed for building the model layer. Apache Tomcat is used as the Web Server, and the view layer, i.e., the user interface, is implemented as Java Server Pages and the controller layer is realized as Java Servlets. The company decides to develop its own DSML called Simple Web Modeling Language (SWM) for defining their specific kind of web applications in a platform-independent way. Furthermore, platform-specific models following the MVC pattern should be derived with model transformations from which the Java-based implementations are finally generated.
The following figure shows the language description of SWM as meta model modeled in EMF Ecore.
A WebModel consists of two parts: a DataLayer for modeling entities which should be persisted in the database (see left-hand-side of the meta model), and a HypertextLayer presenting the web pages of the application (see right-hand-side of the meta model). An Entity owns several Attributes (each having a SimpleType) and can be related to several other entities (see meta class Reference). A Page is either a StaticPage having a static content or a DynamicPage having a dynamic content depending on the referenced entity. An IndexPage lists objects of this entity whereas a DataPage shows concrete information on a specific entity like its name, attributes, and references. Pages are connected by Links.
In the following, we show how to implement quality assurance techniques for SWM. We start with the specification of metrics for the SWM language.
How to specify new model metrics
For the specification of model metrics, EMF Refactor supports four concrete technologies. As basic approaches, pure Java code using the modeling language API generated by EMF and OCL expressions can be used. Another approach is to define a pattern using the abstract model syntax first and to count its occurrences in a concrete model thereafter. These patterns are formulated as rules in a language included in the EMF model transformation tool Henshin [7, 8]. To define compositional metrics, the tool environment supports a combination of existing ones. Here, the involved metrics as well as appropriate arithmetic operations have to be specified.
The specification process is started by selecting File -> New -> Other... -> EMF Quality Assurance -> Metric (...). The following figure shows an example wizard dialog concerning the specification of SWM metric NEM (Number of Entities in the Model).
After inserting metric-specific information like the name or the corresponding meta model and context type information, EMF Refactor generates metric-specific Java code and extends the list of supported model metrics using the extension point technology of Eclipse. Now, the metrics designer has to complete this code by the actual metrics calculation algorithm. As a result, we obtain a module with all metrics features as described here: EMF Refactor Architecture. The following figure shows the completed Java code snippet specifying SWM metric NEM.
Starting from the contextual WebModel element, the Java API of SWM generated by EMF is used. According to the SWM meta model, a web model owns a DataLayer for modeling entities which should be persisted in the database. The custom code simply navigates to the set of entities within the data layer and returns its size (see line 4).
Since EMF models can be queried well using the Object Constraints Language (OCL) [9], EMF Refactor supports model metrics specifications formulated as OCL queries. The following listing shows two alternative OCL expression being suited to calculate SWM metric NDPM (Number of Dynamic Pages in the Model).
The first expression (lines 1 and 2) navigates from the contextual element (represented by the OCL variable self of type WebModel) to the set of pages within the hypertext layer of the model, selects those being of type DynamicPage (since there might be also static pages), and returns their number. The second alternative (line 4) uses the allInstances() operation of the OCL standard library to get a set consisting of all dynamic pages in the model and also returns their number.
To insert the OCL query during the specification process in addition to the basic data (see above), the specification wizard provides a dedicated input page after selecting the OCL specification mode (File -> New -> Other... -> EMF Quality Assurance -> Metric (specified in OCL)). Finally, EMF Refactor generates the complete metric-specific Java code. Here, the contextual element (an instance of WebModel) as well as the specified expression (represented as String) are passed to the OCL adapter.
In order to detect missing dynamic pages, a metric calculating the ratio between the values of both metrics presented before might be helpful. For defining these kind of metrics, the specification wizard provides a dedicated page after selecting specification mode Composite (File -> New -> Other... -> EMF Quality Assurance -> Metric (compositional)). Here, the metric designer simply selects the involved existing metrics as well as the appropriate arithmetic operation. Here, the binary arithmetic operations sum, subtraction, multiplication, and division are supported. In our example, for specifying SWM metric DPpE (Dynamic Pages per Entity), metrics NEM (Number of Entities in the Model) and NDPM (Number of Dynamic Pages in the Model) are combined using the binary arithmetic operation division (see following figure).
To be consistent, the dialog page presents only those metrics whose contextual elements correspond to the contextual element of the new compositional metric (WebModel in our example). Again, EMF Refactor finally generates the complete metric-specific Java code and extends the list of supported model metrics for SWM models.
As a last supported specification mechanism for EMF model metrics we present the use of Henshin pattern rules formulated on the abstract syntax on SWM (File -> New -> Other... -> EMF Quality Assurance -> Metric (specified in Henshin)). The following figure shows a Henshin pattern rule specifying SWM metric NDPE (Number of Dynamic Pages referencing the Entity) using the graphical syntax of Henshin.
The left node context of type Entity represents the contextual model element for calculating metric NDPE whereas the remaining rule elements represent the pattern that has to be found in the model. The pattern defines a node referencingPage of type DynamicPage that references the contextual entity by reference entity. It is formulated as positive application condition (PAC) (see rule elements annotated with <<require#reference>>). To calculate metric NDPE, the Henshin adapter of the metrics tool uses the Henshin interpreter to find and count matches of this pattern rule on concrete SWM instance models. Please note that this adapter requires the following guidelines for Henshin pattern rule specifications to work properly:
- The pattern rule must be named mainRule.
- The rule must have a parameter named index.
- The contextual node must be named index.
For defining these metrics specified in Henshin, the specification wizard provides a dedicated import page for the appropriate Henshin file. As in the cases described before, EMF Refactor finally generates the complete metric-specific Java code and extends the list of supported model metrics for SWM models.
The metrics defined above may help to analyze the completeness of SWM models. However, to make suspicious model parts more explicit, we continue on how to specify model smells for SWM models.
How to specify new model smells
EMF Refactor supports four concrete mechanisms for model smell specification. Again, pure Java code can be used as basic approach. Some smells can be detected well by metric benchmarks. Here, appropriate model metrics are used together with suitable benchmarks being set by project-specific configurations. Pattern-based smells (i.e., smells that are detectable by the existence of specific anti-patterns) can be specified by Henshin rules. The specification process for model smells is similar to the specification process for model metrics. It is started by selecting File -> New -> Other... -> EMF Quality Assurance -> Smell (...). For each specification mode, the dialog page for inserting basic model smell data looks similar to that for specifying a new metric (see above). The only difference is the missing context element type definition since a smell does not have such a context.
After inserting smell-specific information like the name or the corresponding meta model (given by its nsURI), EMF Refactor generates Java code and extends the list of supported model smells using the extension point technology of Eclipse. In the case of selecting the Java specification mode (File -> New -> Other... -> EMF Quality Assurance -> Smell (specified in Java)), the corresponding generation module generates a skeleton implementation that has to be completed by the model smell designer. The following listing shows the core Java specification of SWM smell No Dynamic Page.
This smell occurs if the model contains an entity which is not referenced by a dynamic page, i.e., the entity would not be depicted in the web application. The condition in the if-clause checks whether the given entity is referenced by a dynamic page (line 9). In this case, the boolean flag is set (line 10). Finally, if no page references the entity, i.e., the boolean flag is not set, a new SmellOccurrence object is created, the entity is added to it, and the object is added to the list of found model smells (lines 14 to 16). Please note that the code snippet is not complete since we use auxiliary methods getAllEntities() and getAllDynamicPages() which are not discussed in detail here.
Some model smells can be detected by matching a corresponding pattern based on the abstract syntax of the modeling language. A representative of this kind of smells concerning the SWM language is Equally Named Pages. This smell detects pages within the hypertext layer having the same name. Such redundant page names potentially lead to inconsistent code that is generated from the model. The following figure shows a Henshin pattern rule defining smell Equally Named Pages.
The pattern specifies two pages that must be found in the model (tagged by <<preserve>>) and the containing hypertext layer as PAC (tagged by <<require>>). Furthermore, the rule owns a parameter named pagename of type EString. It is used for specifying that the meta attributes name of each page node have the same value, i.e., the pages have the same name.
The smell detection tool in EMF Refactor uses Henshin’s pattern matching algorithm to detect rule matches. Please note that the pattern rule must be named mainRule in order to be executed by the Henshin adapter. Then, the matches found represent the existence of model smells in the model. If the pattern is matched its preserved nodes represent those model elements which are involved in this specific smell occurrence. The specification process for pattern-based smells is started by selecting File -> New -> Other... -> EMF Quality Assurance -> Smell (specified in Henshin). Again, the specification wizard for pattern-based smells provides an import page for the appropriate Henshin file and finally generates the complete smell-specific Java code and extends the list of supported model smells for SWM models.
As discussed above, metric DPpE (Dynamic Pages per Entity) might be helpful to detect a SWM model smell. If its value is less than 2, i.e., an entity is not referenced by at least two dynamic pages on average, this might be a hint for missing dynamic pages. This metric-based smell is called Insufficient Number of Dynamic Pages in the following. For the specification of metric-based model smells, EMF Refactor provides a dedicated specification wizard (File -> New -> Other... -> EMF Quality Assurance -> Smell (based on a metric)). On a specific page, the metric designer simply selects the corresponding metric as well as the appropriate comparator. For specifying e.g. smell Insufficient Number of Dynamic Pages, metric DPpE is combined with comparator < as discussed above. The following figure shows the corresponding wizard page. Please note that the threshold value is not pre-set. This is done in the project-specific configuration as described above.
Refactoring is the technique of choice for eliminating model smells. So, after having specified appropriate model smells, we demonstrate how to define suitable refactorings in order to support the handling of smelly SWM models in the following.
How to specify new model refactorings
Since EMF Refactor uses the LTK technology [5], a concrete refactoring specification requires up to three parts (i.e., specifications for initial checks, final checks, and the proper model changes). EMF Refactor supports three concrete mechanisms for EMF model refactoring specification. As for metrics and smells, refactorings can be specified using Java and the language API generated by EMF. A way to specify a model refactoring straight forwardly is to use Henshin. Finally, existing refactorings can be combined to more complex ones by using a domain-specific language, called CoMReL (Composite Model Refactoring Language). The specification process of a new model refactoring is triggered by selecting File -> New -> Other... -> EMF Quality Assurance -> Refactoring (...). The upcoming dialog starts with a specification page for inserting basic data like the name of the refactoring or the corresponding meta model and context type information.
A standard refactoring that should be provided for a DSML is the renaming of model elements. For example, refactoring Rename Page can be used to eliminate SWM model smell Equally Named Pages as discussed above. The following figure shows the dialog page for inserting basic information.
After inserting these basic data, potential refactoring-specific parameters are defined using the second page of the specification wizard. Besides the contextual element of type Page, refactoring Rename Page has one more parameter: the new name of the page. It is specified as shown in the following figure.
In addition to the name of the parameter, newpagename, a parameter description can be defined that will be used later on in the parameter input dialog during the refactoring.
If specification mode Java is selected (File -> New -> Other... -> EMF Quality Assurance -> Refactoring (specified in Java)), the generated refactoring-specific code contains three passages indicating those parts of the refactoring specification that have to be completed (i.e., specifications for initial checks, final checks, and the proper model changes). Refactoring Rename Page does not require any initial precondition checks. However, after inserting the new name of the page, a final check has to ensure that there is no page already having this name. The following listing shows the core Java specification of this check.
Here, the name of each page (except for the contextual one) is compared to the specified name given by the parameter input (lines 7 and 8). If there is already a page with this name, an individual error message is added to the refactoring observer (object of LTK class RefactoringStatus; see lines 9 and 10).
The following listing shows the model change specification of refactoring Rename Page. Here, the custom code simply changes the name of the contextual page object (selectedEObject) to the inserted one (line 4).
A prominent way to specify EMF model refactorings is to use the model transformation language Henshin since refactorings can be seen as a specific kind of in-place model transformations. Here, EMF Refactor uses Henshin’s model transformation engine for executing the refactoring as well as Henshin’s pattern matching algorithm to detect violated preconditions.
Above, SWM model smell No Dynamic Page indicating an entity which is not referenced by a dynamic page has been discussed. This smell can be eliminated by a refactoring which inserts both an index page and a data page referencing the corresponding entity to the hypertext layer. This refactoring, called Insert Dynamic Pages, is called from an entity (the contextual element) and can be applied only if this entity is not referenced by a dynamic page already (initial precondition check). The names of both new pages can be derived from the name of the entity by appending Index and Data, respectively. So, the refactoring does not have any further parameters. Therefore, there are no final preconditions to be checked.
In EMF Refactor, the specification of precondition checks using Henshin rules is done in a similar way as for specifying model smells (see above). Each scenario that violates the corresponding precondition is specified in a separate Henshin rule in order to present reasonable error messages to the user. Here, such messages are encoded as descriptions of the corresponding rule. If the rule matches, i.e., the precondition is violated, the Henshin adapter passes the message to the RefactoringStatus object. The following figure shows two Henshin rules defining potential precondition violations of refactoring Insert Dynamic Pages.
In both rules, node selectedEObject of type Entity represents the contextual model element. The rule on the left-hand side specifies that the contextual entity is referenced by a data page whereas the rule on the right-hand side specifies that it is referenced by an index page. Please note that both rules can be combined to one single rule using a node of type DynamicPage instead of two nodes of type DataPage respectively IndexPage. However, when using two rules the corresponding error messages are more meaningful (There is already a data/index page referencing this entity! compared to There is already a dynamic page referencing this entity!).
The following figure shows the Henshin rule specifying the model change part of SWM refactoring Insert Dynamic Pages.
Nodes and edges tagged by <<preserve>> represent unchanged model elements whereas those tagged by <<create>> represent new ones. The rule inserts both a new data page and a new index page into the hypertext layer of the model. The names of the new pages are set as described above. Here, the rule uses an internal parameter entityname whose value is set by the match of the contextual entity (node selectedEObject). Finally, a link between the inserted index page and the new data page is inserted.
Please note that the Henshin adapter requires the following guidelines for refactoring specifications to work properly:
- The unit to be executed must be named mainRule.
- The main unit must have a parameter named selectedEObject.
- The contextual node must be named selectedEObject.
The specification process for refactorings specified in Henshin is started by selecting File -> New -> Other... -> EMF Quality Assurance -> Refactoring (specified in Henshin). Again, the specification wizard provides an import page for the appropriate Henshin file(s) and finally generates the complete refactoring-specific Java code and extends the list of supported model refactorings for SWM models.
EMF Refactor supports to combine existing refactorings to more complex ones. Here, a domain-specific language, CoMReL (Composite Model Refactoring Language), is provided. The following figure shows a visual representation of the specification model of refactoring Create Dynamic Pages for Orphants.
This refactoring can be used to insert both an index page and a data page for each entity in the model which is not referenced by a dynamic page yet. The main refactoring unit Create Dynamic Pages for Orphants is a non-strict SequentialUnit consisting of a SingleQueuedUnit and a AtomicUnit. The SingleQueuedUnit is applied on each entity of the contextual web model. Here, the entities are obtained by helper unit Get All Entities. Finally, refactoring Update Links To Index Pages is applied on the starting page of the model (which is also obtained by an appropriate helper). This additional refactoring is required since the specification of the refactoring does not consider to add a link from the starting page to the newly created index page (see above).
The specification process for refactorings specified in CoMReL is similar to that for Henshin. It is started by selecting File -> New -> Other... -> EMF Quality Assurance -> Refactoring (specified in CoMReL). Here, the specification wizard provides an import page for the appropriate CoMReL file and finally generates the complete refactoring-specific Java code and extends the list of supported model refactorings for SWM models.
So far, we specified several refactorings which are suited to erase model smells specified in the previous section. In the following, we demonstrate how this relation can be made more explicit within the EMF Refactor tool set.
How to specify new smell-refactoring relations
EMF Refactor provides mechanisms to provide modelers with a quick and easy way (1) to erase model smells by automatically suggesting appropriate model refactorings, and (2) to get warnings in cases where new model smells occur due to applying a model refactoring. In order to propose suitable refactorings respectively to inform about potential new smells, the tooling must be provided with information on the relations between model smells and model refactorings.
A pragmatic way is to manually define these relations. Here, the advantage is that the designers can adjust the implementation of model smells and model refactorings to the fact that they are going to be related. A manually defined relation is done by a designer with the definitive goal to erase a model smell using a given model refactoring.
Since there are two possible relationships for model smells and model refactorings, EMF Refactor provides two extension points for the manual definition of these relations as presented in EMF Refactor Architecture. On the one hand, a smell ID is related to a list of refactoring IDs (in case of providing suitable refactorings for a given smell). On the other hand, a refactoring ID is related to a list of smell IDs (in case of possible new smells when applying a given refactoring).
The definition of relations between model smells and model refactorings can be done in two ways: directly (by serving the corresponding extension point) or via a dedicated property page (select project -> menu Project -> Properties -> category EMF Quality Assurance -> subcategory Quick Fix Relations). This page provides graphical user interfaces for (de-)activating appropriate relations. The following figure shows the property page for (de-) activating relations between a given model smell and refactorings being suitable to eliminate this smell.
Here, we address smell No Dynamic Page for SWM models (see meta model selection on the top). For this smell refactoring Insert Dynamic Pages is selected as a potential solution according to the discussions above.
Since the application of a given refactoring poses a risk for inserting new model smell occurrences, EMF Refactor supports the manual configuration of this relationship between model refactorings and model smells. The following figure shows an example for the selection of potentially new smells after applying a specific refactoring.
Here, the afore mentioned SWM refactoring Insert Dynamic Pages is addressed and two smells are specified which can occur after applying the refactoring. On the one hand, smell Equally Named Pages occurs if the hypertext layer already contains a page with the same name as one of the derived names in the corresponding refactoring specification (see above). On the other hand, smell Missing Link occurs since the specification of the refactoring does not consider to add a link from the starting page to the newly created index page.
Please note that the relationships between model smells and refactorings need not be set for each project. Here, EMF Refactor uses the Eclipse extension point technology to provide information about smell-refactoring relationships throughout the entire Eclipse system.
References
[1] Marco Brambilla, Jordi Cabot, and Manuel Wimmer. Model-Driven Software Engineering in Practice. Morgan & Claypool, 2012.
[2] Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Design patterns: Elements of Reusable Object-Oriented software. Addison-Wesley Longman Publishing Co., Inc., 1995.
[3] The Eclipse Foundation. Papyrus, 2014. URL http://www.eclipse.org/papyrus/.
[4] The Eclipse Foundation. Xtext, 2014. URL http://www.eclipse.org/Xtext/.
[5] Leif Frenzel. The Language Toolkit: An API for Automated Refactorings in Eclipse-based IDEs. Eclipse Magazin, 5, 2006. URL http://www.eclipse.org/articles/Article-LTK/ltk.html.
[6] The Eclipse Foundation. EMF Compare, 2014. URL http://eclipse.org/emf/compare/.
[7] Thorsten Arendt, Enrico Biermann, Stefan Jurack, Christian Krause, and Gabriele Taentzer. Henshin: Advanced Concepts and Tools for In-Place EMF Model Transformations. In Model Driven Engineering Languages and Systems (MoDELS), volume 6394 of LNCS, pages 121–135, 2010.
[8] The Eclipse Foundation. Henshin, 2014. URL http://www.eclipse.org/henshin/.
[9] OMG. Object Constraint Language (OCL), 2014. URL http://www.omg.org/spec/OCL/.