Difference between revisions of "EMF/Validation/Recipes"

From Eclipsepedia

Jump to: navigation, search
(Solution)
(Problem)
Line 6: Line 6:
  
 
In case you don't know the purpose of the plugin, it was written to allow OCL constraints to be defined in a text file. These constraints are then applied to a model and can be validated using the Eclipse Validation Framework.
 
In case you don't know the purpose of the plugin, it was written to allow OCL constraints to be defined in a text file. These constraints are then applied to a model and can be validated using the Eclipse Validation Framework.
 +
 +
The Eclipse Validation Framework was developed before the EMF EValator API appeared. In the intervening years alternate approaches have appeared.
 +
*The [[Xtext | Xtext]]-based Complete OCL editor facilitates editing of a Complete OCL document that may be used with the recipe below.
 +
*[[MDT/OCLinEcore#Ecore_Representation | EMF delegates]] support embedding OCL directly as EAnnotations in Ecore models.
 +
* The Xtext-based [[MDT/OCLinEcore | OCLinEcore]] editor facilitates editing these EAnnotations, which then participate directly as part of the static or dynamic EValidator functionality.
 +
*[[Xcore | Xcore]] supports direct maintenance of Java validation code within Ecore models
  
 
=== Solution ===
 
=== Solution ===

Revision as of 12:01, 25 May 2012

Recipe: How To use the Eclipse Validation Framework with OCL constraints defined in a separate file

Problem

I know a lot of people, including myself, have had a lot of trouble getting the very nice org.eclipse.emf.validation.examples.ocl example plugin to work (see the N&N) with their own model/constraints. To this end I have written a quick howto for new users. If you notice any errors please fix them.

In case you don't know the purpose of the plugin, it was written to allow OCL constraints to be defined in a text file. These constraints are then applied to a model and can be validated using the Eclipse Validation Framework.

The Eclipse Validation Framework was developed before the EMF EValator API appeared. In the intervening years alternate approaches have appeared.

  • The Xtext-based Complete OCL editor facilitates editing of a Complete OCL document that may be used with the recipe below.
  • EMF delegates support embedding OCL directly as EAnnotations in Ecore models.
  • The Xtext-based OCLinEcore editor facilitates editing these EAnnotations, which then participate directly as part of the static or dynamic EValidator functionality.
  • Xcore supports direct maintenance of Java validation code within Ecore models

Solution

1. Install Eclipse Modeling Environment from here

  • and if you want to use the Complete OCL editor to edit your OCL text file, install the OCL Examples and Editors from the Modeling

tab of the http://download.eclipse.org/releases/xxxx site.

2. Create a new empty EMF project

  • File->New Project->Empty EMF Project
  • Project name: org.mycompany.product

3. Import an existing EMF model into the new project

  • Select the "model" folder
  • Right click and select Import->File System
    • In this example the model imported is myModel.ecore

4. Create the .genmodel for the EMF model so we can autogenerate the EMF based model editor

  • New->Other->EMF Model
    • Name: Product.genmodel
  • Select Ecore model importer
  • Select the myModel.ecore model

5. Open the new Product.genmodel

  • Select the root object and right click
    • Select "Generate All"

This will create an EMF based editor off the myModel.ecore model

6. Bring the OCL example code into your project

  • File->New->Example->OCL Example
  • File->New->Example->General Validation Example
  • File->New->Example->Validation Adapter Example

7. Delete the following projects as we do not want to use the generated "Library" example settings

  • org.eclipse.emf.examples.library
  • org.eclipse.emf.examples.library.edit
  • org.eclipse.emf.examples.library.editor

and these elements from the org.eclipse.emf.validation.examples.ocl project:

  • src folder
  • Library.ocl file from constraints folder

8. Place our OCL constraints file in the OCL folder in

  • org.eclipse.emf.validation.examples.ocl

Select the "constraints" folder

  • Right click and select Import->File System
    • In this example the constraints imported are Product_constraints.ocl

9. Open plugin.xml in org.eclipse.emf.validation.examples.ocl. Change the last constraintProvider meta-data to match your model's namespace and OCL file

<constraintProvider class="org.eclipse.emf.validation.examples.ocl.OCLConstraintProvider" category="Constraints from an OCL Document">
	<package namespaceUri="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"/>
	<ocl path="constraints/Product_constraints.ocl"/>
</constraintProvider>

10. Edit plugin.xml in org.eclipse.emf.validation.examples.ocl and change the namespaceUri as noted below

  • Delete
http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0
  • Insert
http://www.mycompany/product

11. Fix dependencies in org.eclipse.emf.validation.examples.general

  • Remove the following
org.eclipse.emf.examples.library
org.eclipse.emf.examples.library.edit
org.eclipse.emf.examples.library.editor
  • Insert the following
myProduct
myProduct.editor
myProduct.edit
myProduct.tests

12. Edit plugin.properties in org.eclipse.emf.validation.examples.general

  • Remove the following
EXTLibraryConstraintsCategory=EXT Library Constraints

NonEmptyNameConstraint=Non-Empty Names
NonEmptyNameConstraint.description=All items in an EXT library model
should have some unique identifier or name.

# 0 - An EClass(metaclass) name for the element that was found to have
no unique identifier.
NonEmptyNameConstraint.message=A {0} has been found to have no unique
identifier (name or title).
  • Insert the following
ProductConstraintsCategory=Product Constraints

13. Edit plugin.xml in org.eclipse.emf.validation.examples.general

  • Replace the first <extension/> with the following
<extension point="org.eclipse.ui.editorActions">
	<editorContribution id="org.eclipse.emf.validation.examples.general.editorContribution" targetID="product.presentation.ProductEditorID">
		<menu label="%_UI_ValidationMenu_label" path="Product.ProductMenuID/additions" id="org.eclipse.emf.validationMenuID">
			<separator name="additions"/>
		</menu>
		<action label="%ValidateElementsAction.label" icon="$nl$/icons/elcl16/validate_co.gif" class="org.eclipse.emf.validation.examples.general.actions.BatchValidationDelegate" 
menubarPath="ProductMenuID/org.eclipse.emf.validationMenuID/additions" id="org.eclipse.emf.validation.pde.example.general.ui.validateAction"/>
		<action label="%EnableLiveValidationAction.label" class="org.eclipse.emf.validation.examples.general.actions.EnableLiveValidationDelegate" menubarPath="ProductMenuID/org.eclipse.emf.validationMenuID/additions" 
id="org.eclipse.emf.validation.pde.example.general.ui.enableLiveValidationAction"/>
		<action label="%ShowValidationEventsAction.label" class="org.eclipse.emf.validation.examples.general.actions.ShowValidationEventsDelegate" style="toggle" state="false" menubarPath="ProductMenuID/org.eclipse.emf.validationMenuID
/additions" id="org.eclipse.emf.validation.pde.example.general.ui.showValidationEventsAction"/>
	</editorContribution>
</extension>
<extension point="org.eclipse.ui.popupMenus">
	<viewerContribution targetID="Product.presentation.ProductEditorID" id="org.eclipse.emf.validation.examples.general.viewerContribution">
		<menu label="%_UI_ValidationMenu_label" path="additions" id="org.eclipse.emf.validationMenuID">
			<separator name="additions"/>
		</menu>
		<action label="%ValidateElementsAction.label" icon="$nl$/icons/elcl16/validate_co.gif" class="org.eclipse.emf.validation.examples.general.actions.BatchValidationDelegate" menubarPath="org.eclipse.emf.validationMenuID/additions"
id="org.eclipse.emf.validation.pde.example.general.ui.validateAction"/>
		<action label="%EnableLiveValidationAction.label" class="org.eclipse.emf.validation.examples.general.actions.EnableLiveValidationDelegate" menubarPath="org.eclipse.emf.validationMenuID/additions" 
id="org.eclipse.emf.validation.pde.example.general.ui.enableLiveValidationAction"/>
		<action label="%ShowValidationEventsAction.label" class="org.eclipse.emf.validation.examples.general.actions.ShowValidationEventsDelegate" style="toggle" state="false" menubarPath="org.eclipse.emf.validationMenuID/additions" 
id="org.eclipse.emf.validation.pde.example.general.ui.showValidationEventsAction"/>
	</viewerContribution>
</extension>

14. Edit plugin.xml in org.eclipse.emf.validation.examples.general

  • Remove the following second <extension/>
<extension point="org.eclipse.emf.validation.constraintProviders">
	<category name="%ProductConstraintsCategory" id="org.eclipse.emf.validation.pde.example.general.ui.library"/>
	<constraintProvider cache="true">
		<package namespaceUri="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"/>
		<constraints categories="org.eclipse.emf.validation.pde.example.general.ui.library">
			<constraint lang="Java" class="org.eclipse.emf.validation.examples.general.constraints.NonEmptyNamesConstraint" severity="ERROR" mode="Live" name="%NonEmptyNameConstraint" 
id="org.eclipse.emf.validation.pde.example.general.ui.NameNotEmpty" statusCode="1">
				<description>%NonEmptyNameConstraint.description</description>
				<message>%NonEmptyNameConstraint.message</message>
				<target class="Library">
					<event name="Set">
						<feature name="name"/>
					</event>
					<event name="Unset">
						<feature name="name"/>
					</event>
				</target>
				<target class="Book">
					<event name="Set">
						<feature name="title"/>
					</event>
					<event name="Unset">
						<feature name="title"/>
					</event>
				</target>
			</constraint>
		</constraints>
	</constraintProvider>
</extension>

15. Edit the BatchValidationDeligate.java file in org.eclipse.emf.validation.examples.general.actions. Change the following to reflect your model settings

  • Delete import
org.eclipse.emf.examples.extlibrary.presentation.EXTLibraryEditor;
  • Insert
import Product.presentation.ProductEditor;
  • Delete
protected EXTLibraryEditor editor = null;
  • Insert
protected ProductEditor editor = null;
  • Delete
public void setActiveEditor(IAction action, IEditorPart targetEditor) 
{
	this.editor = (EXTLibraryEditor) targetEditor;
	if ( targetEditor != null ) 
	{
		this.shell = targetEditor.getSite().getShell();
	}
}
  • Insert
public void setActiveEditor(IAction action, IEditorPart targetEditor) 
{
	this.editor = (ProductEditor) targetEditor;
	if ( targetEditor != null ) 
	{
		this.shell = targetEditor.getSite().getShell();
	}
}

16. Edit the EnableLiveValidation.java file in org.eclipse.emf.validation.examples.general.actions. Change the following to reflect your model settings

  • Delete
import org.eclipse.emf.examples.extlibrary.presentation.EXTLibraryEditor;
  • Insert
import Product.presentation.ProductEditor;
  • Delete
protected EXTLibraryEditor editor = null;
  • Insert
protected ProductEditor editor = null;
  • Delete
public void setActiveEditor(IAction action, IEditorPart targetEditor) 
{
	this.editor = (EXTLibraryEditor) targetEditor;
	if ( targetEditor != null ) 
	{
		this.shell = targetEditor.getSite().getShell();
	}
}
  • Insert
public void setActiveEditor(IAction action, IEditorPart targetEditor) 
{
	this.editor = (ProductEditor) targetEditor;
	if ( targetEditor != null ) 
	{
		this.shell = targetEditor.getSite().getShell();
	}
}

17. Edit the NonEmptyNamesConstraint.java file in org.eclipse.emf.validation.examples.general.constraints

  • Delete this file

18. Fix dependencies in org.eclipse.emf.validation.examples.adapter

  • Remove
org.eclipse.emf.examples.library
  • Insert
myProduct

19. Edit Startup.java file in org.eclipse.emf.validation.examples.adapter

  • Delete
import org.eclipse.emf.examples.extlibrary.EXTLibraryPackage;
  • Insert
import Product.ProductPackage;
  • Delete
public void earlyStartup() 
{
	EValidator.Registry.INSTANCE.put(EXTLibraryPackage.eINSTANCE,new EValidatorAdapter());
}
  • Insert
public void earlyStartup() 
{
	EValidator.Registry.INSTANCE.put(ProductPackage.eINSTANCE, new EValidatorAdapter());
}

20. Edit plugin.properties file in org.eclipse.emf.validation.examples.adapter

  • Remove dependency org.eclipse.emf.examples.library

21. Edit plugin.xml file in org.eclipse.emf.validation.examples.adapter

  • Delete
<extension point="org.eclipse.emf.validation.constraintBindings">
	<clientContext id="org.eclipse.emf.validation.examples.adapter">
		<enablement>
			<and>
				<instanceof value="org.eclipse.emf.ecore.EObject"/>
				<test property="org.eclipse.emf.validation.examples.adapter.ePackage" value="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"/>
			</and>
		</enablement>
	</clientContext>
	<binding context="org.eclipse.emf.validation.examples.adapter" category="emf-validation-example"/>
</extension>
  • Insert
<extension point="org.eclipse.emf.validation.constraintBindings">
	<clientContext id="org.eclipse.emf.validation.examples.adapter">
		<enablement>
			<and>
				<instanceof value="org.eclipse.emf.ecore.EObject"/>
				<test property="org.eclipse.emf.validation.examples.adapter.ePackage" value="http://www.mycompany/product"/>
			</and>
		</enablement>
	</clientContext>
	<binding context="org.eclipse.emf.validation.examples.adapter" category="emf-validation-example"/>
</extension>
  • Delete
<constraintProvider cache="true">
	<package namespaceUri="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"/>
	<constraints categories="emf-validation-example/adapter">
		<constraint lang="Java" severity="INFO" mode="Batch" name="%example1.name" id="example1" statusCode="201" class="org.eclipse.emf.validation.examples.adapter.constraints.ExampleConstraint">
			<description>%example1.desc</description>
			<message>%example1.msg</message>
			<!-- This constraint applies to any library element. -->
			<target class="Library"/>
			<target class="Writer"/>
			<target class="Book"/>
		</constraint>
	</constraints>
</constraintProvider>
  • Insert
<constraintProvider cache="true">
	<package namespaceUri="http://www.mycompany/product"/>
	<constraints categories="emf-validation-example/adapter">
		<constrain lang="Java" severity="INFO" mode="Batch" name="%example1.name" id="example1" statusCode="201" class="org.eclipse.emf.validation.examples.adapter.constraints.ExampleConstraint">
		<description>%example1.desc</description>
		<message>%example1.msg</message>
		</constraint>
	</constraints>
</constraintProvider>

22. Create a new Run Configuration so we can see the EMF editor for our myModel.ecore

  • Run->Run->Run as Eclipse Application

This operation will result in a new Eclipse workspace session starting. This new workspace will have the EMF based editor and OCL example plugins built into it.

23. In the new workspace do the following.

  • Create a new empty EMF project
  • File->New Project->Empty EMF Project
    • Project name: myProduct

This will create a project to hold our instance model

24. In the new workspace do the following.

  • File->New->Example EMF Model Creation Wizards
  • Select Product Model
  • File name: my.Product

25. Create a model instance using the EMF editor

26. Validate the using the context menu (right click a model element->Validation->Validate Elements... or simply right click a model element->Validate)

27. Be impressed :)