Jump to: navigation, search

Difference between revisions of "EMF/Validation/Recipes"

(Recipe: HowTo use the Eclipse Validation Framework with OCL constraints defined in a separate file)
(Recipe: HowTo use the Eclipse Validation Framework with OCL constraints defined in a separate file)
Line 132: Line 132:
 
</menu>
 
</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"
 
<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"/>
+
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"  
 
<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"/>
 
id="org.eclipse.emf.validation.pde.example.general.ui.enableLiveValidationAction"/>
Line 149: Line 149:
 
<package namespaceUri="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"/>
 
<package namespaceUri="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"/>
 
<constraints categories="org.eclipse.emf.validation.pde.example.general.ui.library">
 
<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">
+
<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>
 
<description>%NonEmptyNameConstraint.description</description>
 
<message>%NonEmptyNameConstraint.message</message>
 
<message>%NonEmptyNameConstraint.message</message>

Revision as of 11:24, 2 December 2008

Recipe: HowTo 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 http://wiki.eclipse.org/EMF-QTV_1.1_New_and_Noteworthy#New_Validation_Constraint_Provider_Example] 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.

Solution:

1. Install Eclipse Modeling Environment from http://www.eclipse.org/downloads/packages/eclipse-modeling-tools-includes-incubating-components/ganymeder

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 GEF 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 righ click Select "Generate All"

This will create a GEF 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 src folder from under org.eclipse.emf.validation.examples.ocl Library.ocl file from constraints folder in org.eclipse.emf.validation.examples.ocl

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 models 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.adaptor

  • 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 GEF 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 GEF 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 GEF 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 :)