emf_tutorial6 [GMF Samples And Tutorials]
 

Overview

This tutorial is an EMF that shows a simple way to add Java validation rules to a model using the EMF validation Framework. To go fast, it takes the output of the GMF tutorial 7 as an input (in order not to have to build a new ecore model).

The EMF Validation Framework is rich and offers different ways to implement validation rules for a model : you can use annotations, OCL language, and so on. If you are a Java developer, Java language is maybe the best way to implement validation rules, and you maybe don't want to learn OCL, at least for now. If that is the case, you may follow this tutorial to see a simple way to implement your validation rules in Java.

This tutorial is based on the model built in the seventh GMF tutorial wich is availabale through :

Full code is available through :

This tutorial has been built with :

  • Eclipse 3.6
  • Graphical Modeling Framework SDK 2.3.0
  • Eclipse Modeling Framework 2.6.0

By default EMF doesn't run perform validations when resources are saved. You will find a link at the end of this tutorial if you are looking for a plugin enabling on save validation for EMF resources.

EMF invariants

As you may know, it is possible to add operations to an EMF model EClass. On important thing to notice is that if the operation has the following signature : public boolean validate(DiagnosticChain diagnostic, Map<Object, Object> context) then EMF considers that this is an invariant operation.

Once having added your invariant to your ecore model and regenerated your model classes, if you implement the invariant body, it will be evaluated during the default EMF validation process (right click in the tree editor, and Validation).

Tutorial steps

Validation rules

In this tutorial, we will add two invariants.

The first invariant will check if the student has at least on friend. If the rule is not validated, a warning will be generated.

The second will check if a classroom has at least one student. If the rule is not validated, an error will be generated.

Invariant declaration

  • Open the School/model/school.ecore file
  • Add an EOperation to the Student Eclass with the following properties :
    • Name : validate
    • EType : EBoolean
  • Add an EParameter to the EOperation you've just created with the following properties :
    • Name : diagnostic
    • EType : EDiagnosticChain
  • Add another EParameter to the EOperation you've just created with the following properties :
    • Name : context
    • EType : EMap
    • Open the parameter node in the tree editor, open the EMap<?, ?> node and for each child node : select the EJavaObject value for the EClassifier property

  • Copy/paste the validate operation from the Student to the School EClass.

Invariant implementation

  • Open the School/model/school.genmodel file
  • Regenerate the model code (Right click on the root node, and Generate Model Code)
  • Open the StudentImpl class and go to the validate method.
  • Add NOT after the @generated string in the javadoc comments
  • Replace the generated implementation by the following code :
/**
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated
 */
public boolean validate(DiagnosticChain diagnostic, Map<Object, Object> context) {
	boolean valid = true;
	if (diagnostic != null) {
		if (getFriends().size() == 0) {
			valid = false;
			diagnostic.add(new BasicDiagnostic(Diagnostic.WARNING,
					SchoolValidator.DIAGNOSTIC_SOURCE,
					SchoolValidator.STUDENT__VALIDATE, "The student '"
							+ getName() + "' has no friend.",
					new Object[] { this }));
		}
	}
	return valid;
}
  • Open the ClassroomImpl class and go to the validate method.
  • Add NOT after the @generated string in the javadoc comments
  • Replace the generated implementation by the following code :
/**
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated NOT
 */
public boolean validate(DiagnosticChain diagnostic, Map<Object, Object> context) {
	boolean valid = true;
	if (diagnostic != null) {
		if (getStudents().size() == 0) {
			valid = false;
			diagnostic.add(new BasicDiagnostic(Diagnostic.ERROR,
					SchoolValidator.DIAGNOSTIC_SOURCE,
					SchoolValidator.CLASSROOM__VALIDATE, "The classroom '"
							+ getName() + "' has no student.",
					new Object[] { this }));
		}
	}
	return valid;
}

Run and test

  • Run the eclipse configuration that had been created in the first tutorial.
  • Suppose you've created a School model with two classrooms, the first with no student, the second with one only student. If you right click on the root node of the EMF tree editor and select Validate, you may get this result :

"On save" validation

  • By default, EMF doesn't validate an EMF resource when it is saved (as you are probably used to with the eclipse java environment, JDT).
  • For example, in the previous example, if you add a student in the first classroom and save the file, the error indicating that the classroom has no student persists unitl you re-run the validation through the tree editor.
  • If you want your validation rules to be re-evaluated whenever your model files are saved, you can use “EMF Validation Builder” which is available for free (go here for more details).

Thank you

I hope that this material will be helpful for you. If you want to support it, your help is welcome :

Discussion

Kieara Belle, 2011/09/08 11:58

Hello,

I have been given a project to model a transactional language and allow the User to develop a process from the same in a Graphical Editor. I have done this, in GMF and the user can draw (make) the diagrams in the editor. The next task is to incorporate the semantic rules of the language (like structural congruence and reduction relations) and then based on these rules I am supposed to make a functionality that gives user an option to 'Transform' a particular diagram into a resulting diagram.

For example : if there are 2 processes in an editor diagram (made by the user), one of them Process Q is a SUCCESS and other is a normal process and both are in sequence i.e (Process P followed by another Process Q(which is a SUCCESS) ) then the result of this should be another editor diagram that shows only Process P. (as this is how the language rules defines such a sequence)

The doubts I have are :

1) How do I read the editor diagram in a file/code in order to generate the other editor diagram ? 2) Which files or codes (generated by GMF genmodel / EMF genmodel ) am I supposed to write all this code in ? 3) What structure should I follow ? 4) How do I add the functionality 'Transform' on the context Menu in the Eclipse instance (or the Editor window) ?

Also, I have a node T with 3 compartments, I want that when I click on the compartment, a new diagram editor should open up and allow me to add the same type of components. (i.e the meta-model, gmfgraph, gmfmap, gmftools will be the same ). In simpler terms, the compartments should contain a diagram. Also is it possible to add the diagram within that compartment rather than opening a new editor (Eclipse Instance)?

Thanks Kieara

Jean-François Brazeau, 2011/12/08 21:08

How I think I have already answered this question in the fifth tutorial… Sorry for the delay, I think that my answer has come too late…

Arun , 2014/07/29 09:37

Dear All,

Just to improve the tutorial and automate the process, i.e., to avoid playing with the generated code, one could make use of annotations in the model and generate them. You could follow the following steps:

1. After the “Invariant declaration” step, right click the class and add a new annotation. 2. Enter the source as “http://www.eclipse.org/emf/2002/GenModel”. 3. Right click the annotation and add a new “Details Entry”. Set the key as “body” and in the value add the java code that you want to get generated.

More information at http://www.vogella.com/tutorials/EclipseEMF/article.html#methods

Thanks again for the great tutorial.

Cheers Arun

 
emf_tutorial6.txt · Last modified: 2011/08/08 20:05 by jfbraz
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki