Refactoring

Table of Contents

logo-large

Tutorial Actifsource Tutorial – Refactoring
Required Time - 45 Minutes
Prerequisites - Actifsource Tutorial – Installing Actifsource
- Actifsource Tutorial – Simple Service
Goal - Writing an aspect for refactoring instances
- Refactor instances to match the new specification literals
- Update templates
Topics covered - Create and register a refactoring aspect
- Update the simple service model
- Execute a refactoring
- Update the templates
Notation ↪ To do
ⓘ Information
Bold: Terms from actifsource or other technologies and tools
Bold underlined: actifsource Resources
Monospaced: User input
Italics: Important terms in current situation
Disclaimer The authors do not accept any liability arising out of the application or use of any information or equipment described herein. The information contained within this document is by its very nature incomplete. Therefore the authors accept no responsibility for the precise accuracy of the documentation contained herein. It should be used rather as a guide and starting point.
Contact Actifsource AG
Täfernstrasse 37
5405 Baden-Dättwil
Switzerland
www.actifsource.com
Trademark Actifsource is a registered trademark of Actifsource AG in Switzerland, the EU, USA, and China. other names appearing on the site may be trademarks of their respective owners.

Overview

  • Create and register a refactoring aspect

image2 image2

  • Update the simple service model

image3 image3

  • Write a simple refactoring

image4 image4

  • Execute the refactoring

image5 image5

  • Update the templates

image6 image6

Part I Create and register a refactoring aspect

Setup a project

image7 image7

  • Open the project created during the Actifsource Tutorial Simple Service or make an new one with the new project with name and namespace ch.actifsource.tutorial.refactoring as shown in this tutorial
  • Create a new Package with name refactoring
  • Create a Refactoring resource of type ch.actifsource.ui.refactoring.Refactoring with name Refactoring

image3 image3

  • You need to convert this project to a Eclipse Plugin Project
  • Right click on the project ch.actifsource.tutorial.builtin in the navigator to open the context menu.
  • Go into the submenu Configure and click on Convert to Plug-in Projects…

image4 image4

  • Check the checkbox in front of ch.actifsource.tutorial.refactoring
  • Click Finish

image5 image5

  • This will convert the project however there will be some error and warning needed to be fixed.

image6 image6

  • Right click on the Actifsource classpath container
  • Go into the submenu Build Path and select Remove from Build Path

Create and register a refactoring aspect

image8 image8

  • Open the MANIFEST.MF

image9 image9

  • Add a dependency to the ch.actifsource.core" and the ch.actifsource.ui.refactoring-Plugin

image10 image10

  • Create a new java source folder for the aspect implementation.

image11 image11

  • We recommend naming the new source folder src-aspect
  • Click Finish

image12 image12

  • Create a new java class extending the ch.actifsource.core.model.aspects.impl.AbstractRefactorerAspect class

image13 image13

  • Add the following constructor function to the class
public CallGroupRefactoringAspect() {
  super("1.0.0",
        Date.from(LocalDate.of(2024, 1, 6).atStartOfDay(ZoneId.systemDefault()).toInstant()),
        "Call to Callgroup");
}
  • The first parameter defines a version string for the aspect. The following three parameters are used to specify the date when the refactoring was written.The last parameter is the name. The arguments are shown in the dialog and used to sort the refactoring aspects.

image2 image2

  • Register the java class in the Refactoring instance

image14 image14

  • The result should look like above. There must be no more model inconsistencies be present.

Part II Update the simple service model

image15 image15

  • Open the Service class
  • Select the call relation and cut the resource by using the clipboard (Ctrl+X)

image16 image16

  • Create a new Relation named group with a new Class named “CallGroup” used as the range

image17 image17

  • Paste the call relation from the clipboard into the new Callgroup

image18 image18

  • Add an additional Attribute named async of type boolean with default value false
  • We only use an attribute to keep the tutorial simple. An alternative would be to create a subclass of CallGroup instead.

Part III Write a simple refactoring

Select project Properties Select project Properties

  • First we want to have more convenient access to the resource guids.
  • To accomplish this, we need to check a setting in the project settings of ch.actifsource.tutorial.refactoring
  • Right-click on the project and select Properties

actifscource project Properties actifscource project Properties

  • Check in the actifsource settings whether the option “generate javamodel” is set

image19 image19

  • If the “generate javamodel” option is not set, this can be set or add a the ExportWithoutStatements buildconfig to the src-gen target folder for exporting java classes for the SimpleService packages
  • This will generate a class for each package containing a constant for each resource.

actifscource project Built-in Dependencies actifscource project Built-in Dependencies

-If you cannot use the buildconfig ExportWithoutStatements, check in the Built-in Dependencies tab whether the JAVAMODEL is available. If not, add it via the Add Builtin button.

  • Implement the refactor method

image20 image20

  • The refactor method has only two parameters an IModifiable and a list of packages. The modifiable provides the context to access the actifsource resources. The package list contains the actifsource packages selected by the user when starting the refactoring. How the packages selection is interpreted is up to the implementer.

  • In general you need to use the two classes Select and Update. These are facades providing a convenient way to select and update resource information in a context. To get information about the available methods, open the class and a have a look at the javadoc comments on how to use them.

  • The actifsource API works with statements and resources. A Statement is a triple connecting two resources (subject, object) through a property (predicate). The subject is the resource whose type (class) defines the predicate (property). The object is an instance of properties range. This is almost the same you see in the resource editor. In our example Patient is an instance of Service Person refers the Call throw the call defined in the Service class. For example you will get a statement Person (subject), call (predicate), Create (object) because Person refers to Create through the call relation. This is different from the diagram editor where subject and object are represented by their type.

  • The old model looked like this

    image3 image3

    and the new model looks like this now

    image21 image21

The only thing the refactoring has to do is adding a CallGroup into each Service and move the Call into the group.

image22 image22

  • Select all Service instances in packages posted to the refactorer
  • The instanceWithPackage method takes an ISelectable and the GUID of a class. The result is an Iterable providing all instances reachable through the selectable. Since each IModifiable is also an ISelectable, you can use the IModifiable passed to the refactorer.

image23 image23

  • Create a new CallGroup using the Update-Facade and add it to the Service-Instance
  • The Update-Facade always requires an IModifiable to work with. Using the createAndInitializeResource method you can create a new instance of a type in the specific package. If you have a named resource, it is recommended to use the overload taking a name, in this case group. The last parameter defines the default values for the attributes and relations when creating the resource and can be left out. For each property not found in the defaultValue map the default defined in the model will be used.

image4 image4

  • Move the Call to the group
  • This time the method is located on the RefactorUtil. The reason for this is that the Update-Facade only provides simple modification methods and no selects. The moveStatements method uses methods from both the Select and Update method and is more complex. The moveStatements method take the IModifiable, a Property, the source and the target. It is simply often used when moving a Property from one class to another.
  • By using the cut and paste in ResourceEditor, actifsource automatically detected that you have moved the Property call

Part IV Execute a refactoring

image24 image24

  • Open the Patient to see that it is actually invalid.
  • As you can see the group relation that is already there and it would be possible to do change the model by hand.

image25 image25

  • Open the context menu on the project or the package containing the Patient service

image26 image26

  • Select the Call to Callgroup.
  • Press Finish.

image27 image27

  • The Patient service is now refactored
  • As you can see, the values passed to the constructor are shown in the refactoring dialog. In actifsource we use the aspects to provide refactorings whenever we change the metamodel.

Part IV Update the templates

image28 image28

  • The refactoring you have written only updates the instances. This is common practice, writing a refactoring for the service model and the templates makes no sense, since updating the classes is different for each step. The same applies for the templates.
  • Open the ServiceImpl template
  • Go to the Service.call selector by clicking on the first errormarker
  • Change it to Service.group.call

image6 image6

  • Add a new line using the async attribute

image29 image29

  • Open the generate PatientImpl.java and update the protected regions.
Tip

You may play around a little bit with the model by adding an additional CallGroup to the Patient with the async attribute set to true.

actifsource-point-large