Eclipse Modeling Tools tutorial - Constraints and invariants in EMF [screencast]
This tutorial is the continuation on my tutorial to create a simple model. Here I present how to add constraints to the model. I focus on the Java constraints. In an upcoming tutorial I plan to show how to do validation in OCL.
Hi I'm Edmundo and welcome to my Eclipse Modeling tutorial. In this lesson I'm showing you how to create constraints for your model.
I'm using Eclipse Modeling Tools Luna SR 1.
I focus on standard EMF constraints, this is constraints written in Java. The plan is the following: First a little bit of theory, I'll explain how EMF makes the difference between constraints and invariants. Then, I'll present the constraints I'm implementing, and finally, I'll do the demo on how to add the constraints.
Constraints vs Invariants
EMF distinguishes between constraints and invariants. Semantically speaking, invariants are stronger than constraints. The idea is that invariants are always valid while constraints only need to be valid at specific times.
This is only theory, but EMF also makes a practical distinction between them. When generating code invariants will be implemented as members of the class, and constraints are implemented in an external class.
The implication of this is that invariants have access to the private state of the object, while constraints don't. Also, this means that for invariants you could check the validity of a class even before returning from some private class method.
The constraints we are implementing
We are using the accounting model explained in a previous lesson. You can see the lesson at edmundo.lopezbobeda.net/accountingmodel . A downloadable version of the model is available for the mailing list subscribers.
I'd like to add following constraints to the model:
First, the code of an account needs to be a numeric string. Second, the code of a sub account needs to start with the same string as the account. For example if account code is "1", the code of all children subaccounts has to start with 1.
I'll first create a constraint for the numeric string. I first select the class where I want to add a constraint. Then, in the Properties View I go to Annotation and add an annotation with the following source. Then, while the annotation is selected, in the lower part of the panel I click on Add to add an entry. The key of the entry is "constraints", with an s. In the value of the entry I enter a name for the constraint, I'm calling it "NumericCode". Be careful that the editor is a little buggy but in the end it will allow you to add your constraint. If I need to have several constraints I just separate each name with a space. The name has to be a valid Java identifier.
Before launching the code generation let us create the invariant. Invariants are uglier. To create an invariant I need to add a class method for the invariant. If the class method has the right signature, the code generation engine will generate the necessary code. First I create a method for the sub account class. Now I rename it to "isDerivedFromParent" and set its type to boolean. Then I add the parameters. The graphical editor is not very stable for adding parameters. So we are adding them directly in the ecore file. I need one DiagnosticChain parameter and one Map. First I add the DiagnosticChain parameter. I just right click the function, select "New child"->Parameter and set the type and the name. Then I do the same for the Map parameter.
Finally, we generate the code as always. We go the genmodel file, right click on the root and click Generate Model Code. You'll notice that the generated code does not compile. The workaround is simple, just remove the type parameters of Map. As you can see the skeleton for the invariants code has been generated. In the same way, in the package accounting.util the AccountingValidator class has been generated. This class contains the skeleton for our constraint.
- The good old eclipse documentation on constraints and validation