I'm working on a project in EMF, where I have created a simple order system. A part of the system is presented on the picture below:
So an OrderItem
object will have a reference to only one product and its price will be calculated by the quantity
of OrderItem
times the price
of the Product
. The attribute isValid
must be set whenever OrderItem.quantity
changes, e.g. if Product.quantity < OrderItem.quantity
then set isValid=false
else true
.
My question is how can I achieve this, so when I am creating an instance of the model using the Editor or changing some instance variable, dependent variables are updated automatically? (Should I rewrite the generated code? Should I override the set()
method using Annotation
? Should I use AQL or Services?) Thank you!
The scenario that you present touches on an important aspect of EMF and model-driven engineering in general, model validation.
Model validation, as the name suggests, is the process of checking whether a model is valid or not. EMF provides a convenient mechanism for this that can help you keep implementation complexity under control.
EMF defines two concepts related to model validation, invariants and constraints.
Invariants are assertions about your models that must be true at all times, whereas constraints are assertions about your models that must be true at some point in time (before executing a certain process perhaps). I cannot tell from your question whether you would like to check product quantities only before shipping for example or constantly check them. It is an application-specific decision that is up to you. I will explain invariants below.
In terms of Ecore model, invariants are defined as operations of the class whose instances you are validating. Here for example for the class OrderItem, you would add an Operation (named checkProduct quantity for example). Operations that represent invariants need to return EBoolean and accept two arguments, one EDiagnosticChain and one EMap argument.
Once you add the above to your Ecore model, the EMF generator will detect that you want to define an invariant and will generate a specific method, as well as a utility class YourDSLValidator. You need to manually modify the generated method based on the things you are validating. For example here, you would have something like the following.
You would then basically modify the
if(false)
part toif(this.quantity < this.OrderItem.getQuantity)
With the above you can now validate your models programmatically but also validate them inside the generated eclipse editor.
There are a lot of extra functionality that EMF provides. If you would like to find out more about EMF internals, I would definitely recommend the EMF book https://www.informit.com/store/emf-eclipse-modeling-framework-9780321331885 as it has a lot of information that is not available with a simple google search.