Previous Tutorial: Creating an OPM GEF Editor – Part 13: Adding Procedural Links
In the last tutorial we modified the model adding both procedural links and something called a
OPMStrucuralLinkAggregator. Structural links in OPM define structural relations between elements in the model, and are drawn using different kinds of triangles that are connected on one side to the source (or parent) of the relation, and on the other side are connected ALL of the targets (or childs) of the relation. So the structural link in an OPD consists of at least three figures: a source link from the source to the triangle, the triangle itself and a link from the triangle to the target. The way I decided to implement this is to create a model element called
OPMStructuralLinkAggregator which is a
OPMNode in the diagram. This implementation reuses some of the functionality previously coded for
OPMThing instances and is also relatively easy to code.
BTW, this is one of the places where design decisions are difficult. Because my knowledge of the GEF framework is not really deep, I decided to implement this feature basically the only way I knew possible. But maybe I could have implemented it by extending GEF’s
Connection, implementing also a special
Locator to draw the triangle in the middle of the
Connection and create multiple links from the triangle to the target things by connecting a
Connection to the triangle using an
Anchor in the existing connections. This may be a more elegant solution but I am not sure that all of what I just said can be really implemented, so as a wise man said “If it’s stupid but it works, it isn’t stupid.”.
But before we delve into the implementation of the new feature, we are going to use some really cool features of the eclipse workbench that help you refactor your code. Refactoring, as defined by Martin Fowler, “is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.”. And what better way to make sure that no external behavior is changed than to use the (surely) extensively tested refactoring operations or our IDE? So here are some of the operations that help us refactor our code to make it more generic for the next step or our tutorial.
- We will create the
OPMNodeclass using the extract superclass. Right click on the
OPMThingEditPartand select “Refactor”->”Extract Superclass…”.
A wizard opens up asking us the name of the new superclass and how we want to extract the class – what methods to transfer, maybe set some of them abstract, etc. There are many possibilities and I recommend you go and learn some of them (you can always undo what the wizard does, even if the change encompasses a number of files).
We’ll name our new class
OPMNodeEditPartand for now will extract the
getModelTargetConnectionsmethods, because in our new model the source and target connections are stored in the
OPMNode. Click “Next”.
Now we are asked what methods we want removed from the original class.
In this simple example we remove the two methods that we just transfered to the superclass. Click “Next”.
The wizard now shows us what changes will be applied to files we changed. Review your changes to understand what just happened.
Saves some heavy handwork, right? And it is also done with zero errors, which is probably much better than human hands. Press “Finish” and voila! we have done our first refactoring!.
- The next refactoring operation we are doing is called “Generalize Declared Type”, and it lets the user try to change the type of a declared reference to a more general one (a superclass or interface). While this may seem pretty simple, it automatically calculates from the code to which superclassees (or interface) the declared reference can be changed, which is pretty neat. So let’s
OPMNodeEditPartfile, select a
OPMThingdeclaration, right click and select “Refactor”->”Generalize Declared Type…”.
A wizard page opens up and shows us the available types to which the selected reference can be generalized.
Not many possibilities.. so select the
OPMNodeinterface (if it’s not selected already) and click “Preview”.
The final wizard page shows us the changes that will be applied to the code. It is a very good practice to always read this just in case the refactoring operation we chose didn’t exactly behave as we expected.
Click “OK” and we are done (Hey, did you notice that the previous wizard’s last page had a “Finish” button and this one has a “OK” button? Should I file a but to the eclipse team? :-)).
- Going back to the
OPMThingEditPartclass, there is more functionality that can be transfered to its parent class, for it to be used later by the
OPMStructuralLinkAggregatorEditPartwhich will also inherit from
OPMNodeEditPart. First thing we notice is that the internal
OPMThingAdapterclass checks no logic specific to a
OPMThingwhen notified and simply refreshes the
EditPart. Therefore we can move the
OPMThingAdapterto its parent class and generalize the behavior. This is just a few click away. Select the
OPMThingEditPart, right click and select “Refactor”->”Move…”.
A wizard window opens up and asks us where we want to put the class.
As said before, the class will be moved to the
OPMNodeEditPart. Select it and click “Preview”. I said it before and I will say it again: it never costs you too much to preview what the wizard is doing, and not looking may cost you much more later. So until you are really comfortable with the refactoring operations and you really know what you are doing, I definitely recommend previewing the changes before applying them.
Looks like it is doing what we wanted, so click “OK”.
- Last refactoring we’ll be doing today is called “Pull Up”, and it moves a method (or field) from a class to a superclass. We’ll be doing this to the
deactivatemethods in the
OPMThingEditPartwhich will sit more naturally in the
OPMNodeEditPartnow that the
OPMThingAdapterwas moved there (BTW, the name of the adapter should also be changed but class renaming is very simple refactoring so I’ll let you do that by your own). Once again open the
OPMThingEditPart, click somewhere inside the class and select “Refactor”->”Pull Up…”.
A wizard page opens up asking what elements of the class we want to “pull up”, and where in the hierarchy of the class we want to put them. Like in the “Extract Class” refactoring operations, there are more options that should be investigated in your free time.
deactivatemethods to pull up to the
OPMNodeEditPartclass and click “Next”.
The next wizard page asks us which methods to remove from the subclass(es).
In our simple case we just remove the same methods we just pulled up. Click “Next” one more time.
The last wizard page gives us a preview of the changes that will be applied to the source code.
If you are satisfied with the changes, click “Finish”.
Code refactoring is a very powerful way to clean an organize your code without messing things up :-). A full list of the refactoring operations that are available in eclipse can be found here. There is a great world to explore and what better day than today to start? Enjoy.
Next Tutorial: Creating an OPM GEF Editor – Part 15: Adding Structural Links.