Jump to: navigation, search

Difference between revisions of "EMF/New and Noteworthy/Helios"

< EMF
(Support for Validation Delegates)
(Support for Validation Delegates)
Line 9: Line 9:
 
==== Support for Validation Delegates  ====
 
==== Support for Validation Delegates  ====
  
The EMF Validation Framework previously supported evaluation of invariants as constraints, defined as methods and implemented in Java, via a validator that is invoked at important moments by an application or at a user’s discretion. In order to delegate evaluation of invariants and constraints to an external engine, the framework was enhanced by introducing the concept of a validation delegate, based on a well-defined interface.  
+
The EMF Validation Framework previously supported evaluation of invariants and constraints, defined as methods and implemented in Java, via a validator that is invoked at important moments by an application or at a user’s discretion. In order to delegate evaluation of invariants and constraints to an external engine, the framework was enhanced by introducing the concept of a validation delegate, based on a well-defined interface.  
  
 
====== Defining a Validation Delegate  ======
 
====== Defining a Validation Delegate  ======
  
The contract between a validation consumer (a validator and/or diagnostician) and provider (an external expression engine) is defined in a new interface, '''ValidationDelegate''', defined as an inner member of the previously existing '''EValidator''' interface.  
+
The contract between a validation consumer (a validator and/or diagnostician) and provider (an external expression engine) is defined in a new interface, '''ValidationDelegate''', an inner member of the previously existing '''EValidator''' interface.  
  
 
[[Image:ValidationDelegate.png]]  
 
[[Image:ValidationDelegate.png]]  
  
Classes that implement this interface define methods that call out to the desired external engine to evaluate the expression (passed as the last argument) based on the class or data type and corresponding instance value and return a Boolean result.
+
Classes that implement this interface define methods that call out to the desired external engine to evaluate the expression (passed as the last argument) based on the class or data type and corresponding instance value, and return a Boolean result.
  
 
'''''Example'''''
 
'''''Example'''''
Line 47: Line 47:
 
====== Referencing a Validation Delegate ======
 
====== Referencing a Validation Delegate ======
  
In order to use a validation delegate in a particular Ecore model, it has to be referenced in an annotation on the package enclosing the elements on which the invariants and constraints are defined. The source for this annotation must be “http://www.eclipse.org/emf/2002/Ecore” (the usual source for Ecore annotations) and the details key must be “validationDelegates”. Note that the details key is plural because it is possible to reference multiple validation delegate URIs, each separated by a space in the value for the key.
+
In order to use a validation delegate in a particular Ecore model, it has to be referenced in an annotation on the package enclosing the elements on which the invariants and constraints are defined. The source for this annotation must be “http://www.eclipse.org/emf/2002/Ecore” (the usual source for Ecore annotations) and the details key must be “validationDelegates”. Note that the details key is plural because it is possible to reference multiple validation delegate URIs, each separated by a space, in the value for the key.
  
 
'''''Example'''''
 
'''''Example'''''
Line 73: Line 73:
 
====== Evaluating an Invariant ======
 
====== Evaluating an Invariant ======
  
Once the behavior of an invariant has been defined, it can be evaluated either statically via generated code or dynamically via EMF reflection. Of course, a given expression engine will need to support EMF reflection in order to successfully evaluate expressions on dynamic models. The default code that is produced by the EMF code generator has been altered to delegate evaluation of the expression in an operation’s annotation to the corresponding validation delegate. Built-in support has also been added to the base validator implementation ('''EObjectValidator''') so that delegation of expression evaluation also takes place for non-generated models, in a fashion similar to the previously existing support for dynamic validation of data type restrictions. With these changes, modelers are now able to define and evaluate the behavior of invariants, either statically or dynamically, without having to alter a single line of code.
+
Once the behavior of an invariant has been defined, it can be evaluated either statically via generated code or dynamically via EMF reflection. Of course, a given expression engine will need to support EMF reflection in order to successfully evaluate expressions on dynamic models. The default code that is produced by the EMF code generator has been altered to delegate evaluation of the expression in an operation’s annotation to the corresponding validation delegate. Built-in support has also been added to the base validator implementation ('''EObjectValidator''') so that delegation of expression evaluation also takes place for non-generated models, in a fashion similar to the previously existing support for dynamic validation of data type restrictions. With these changes, modelers are now able to define and evaluate the behavior of an invariant, either statically or dynamically, without having to alter a single line of code.
  
 
====== Defining the Behavior of Constraints ======
 
====== Defining the Behavior of Constraints ======

Revision as of 12:31, 23 September 2009

Eclipse EMF Core New and Noteworthy items for the Helios release.

For more details about the development plan, see the EMF Helios draft plan.

Milestone 2

This milestone was completed on Friday October 2, 2009.

Support for Validation Delegates

The EMF Validation Framework previously supported evaluation of invariants and constraints, defined as methods and implemented in Java, via a validator that is invoked at important moments by an application or at a user’s discretion. In order to delegate evaluation of invariants and constraints to an external engine, the framework was enhanced by introducing the concept of a validation delegate, based on a well-defined interface.

Defining a Validation Delegate

The contract between a validation consumer (a validator and/or diagnostician) and provider (an external expression engine) is defined in a new interface, ValidationDelegate, an inner member of the previously existing EValidator interface.

ValidationDelegate.png

Classes that implement this interface define methods that call out to the desired external engine to evaluate the expression (passed as the last argument) based on the class or data type and corresponding instance value, and return a Boolean result.

Example

A validation delegate for OCL expressions might be implemented as shown below.

OCLValidationDelegate.png

It is the responsibility of the calling validator to handle runtime exceptions and to process validation failures, by adding a diagnostic of a suitable severity to the diagnostic chain for the validation operation, with a suitable message.

Registering a Validation Delegate

A registry, following the familiar pattern for similar registries in EMF, provides the means by which validators and diagnosticians discover validation delegates. The interface for this registry is defined as an inner member of the ValidationDelegate interface, described above.

ValidationDelegateRegistry.png

As with other EMF registries, an extension point is defined for the global (default) validation delegate registry. Thus, it is possible to register validation delegates against dedicated URIs either statically (by declaring their classes against URIs in an extension based on the extension point) or dynamically (by programmatically adding a validation delegate instance directly to a registry).

Example

The validation delegate implemented for OCL might be registered statically with the default registry as shown below.

StaticOCLValidationDelegateRegistration.png

Alternatively, the validation delegate could be registered programmatically with the default registry as shown below.

DynamicOCLValidationDelegateRegistration.png

Referencing a Validation Delegate

In order to use a validation delegate in a particular Ecore model, it has to be referenced in an annotation on the package enclosing the elements on which the invariants and constraints are defined. The source for this annotation must be “http://www.eclipse.org/emf/2002/Ecore” (the usual source for Ecore annotations) and the details key must be “validationDelegates”. Note that the details key is plural because it is possible to reference multiple validation delegate URIs, each separated by a space, in the value for the key.

Example

The validation delegate for OCL expressions, as defined above, could be referenced from a model (the extended library example model from EMF) as shown below.

OCLValidationDelegateReference.png

Overriding a Validation Delegate

In some cases, more than one engine might be available to evaluate expressions in a particular language; however, only one delegator can be registered against a given URI in the global registry. To allow for the possibility of this default validation delegate to be overridden, the default validation delegate registry implementation supports delegation to another registry (e.g., the global one) in much the same way as the Ecore package registry in EMF can delegate to another registry.

Defining the Behavior of an Invariant

As mentioned above, EMF’s previous support for invariants amounted to generated method stubs on Java classes which had to be implemented by hand. Once a validation delegate has been implemented, registered, and referenced from an Ecore package, however, it is now possible to define and evaluate the behavior of an invariant in a language other than Java (i.e., the language supported by the validation delegate).

In order for the behavior of an invariant to be defined in an arbitrary language (supported by a validation delegate), it has to be specified in an annotation on the operation representing the invariant. The source for the annotation must match the URI for one of the validation delegates referenced by the enclosing Ecore package. The key for the details entry must be “body” and the value must be a string expression that can be evaluated by the referenced validation delegate. The severity for delegated invariant expressions is ERROR by default, and a standard validation failure message is used; this can be overridden (for static models) by customizing the generated code.

Example

The behavior for an invariant which asserts that a writer must not write books in more than two genres could be defined as an OCL expression in an annotation as shown below.

DelegatedOCLInvariant.png

Evaluating an Invariant

Once the behavior of an invariant has been defined, it can be evaluated either statically via generated code or dynamically via EMF reflection. Of course, a given expression engine will need to support EMF reflection in order to successfully evaluate expressions on dynamic models. The default code that is produced by the EMF code generator has been altered to delegate evaluation of the expression in an operation’s annotation to the corresponding validation delegate. Built-in support has also been added to the base validator implementation (EObjectValidator) so that delegation of expression evaluation also takes place for non-generated models, in a fashion similar to the previously existing support for dynamic validation of data type restrictions. With these changes, modelers are now able to define and evaluate the behavior of an invariant, either statically or dynamically, without having to alter a single line of code.

Defining the Behavior of Constraints

As mentioned above, EMF’s previous support for constraints amounted to generated method stubs on a Java class (the validator for a package) which had to be implemented by hand. Once a validation delegate has been implemented, registered, and referenced from an Ecore package, however, it is now possible to define and evaluate the behavior of constraints in a language other than Java (i.e., the language supported by the validation delegate).

In order for the behaviors of constraints to be defined in an arbitrary language (supported by a validation delegate), they have to be specified in an annotation on the class or data type where the constraints are declared. The source for the annotation must match the URI for one of the validation delegates referenced by the enclosing Ecore package. One or more details entries, whose keys match the names of declared constraints and whose values are string expressions that can be evaluated by the referenced validation delegate, can be specified. The severity for delegated constraint expressions is ERROR by default, and a standard validation failure message is used; this can be overridden (for static models) by customizing the generated code.

Example

The behavior for a constraint which asserts that a book must have a title could be defined as an OCL expression in an annotation as shown below.

DelegatedOCLConstraint.png

Evaluating Constraints

Once the behaviors of constraints have been defined, they can be evaluated either statically via generated code or dynamically via EMF reflection. Of course, a given expression engine will need to support EMF reflection in order to successfully evaluate expressions on dynamic models. The default code that is produced by the EMF code generator has been altered to delegate evaluation of the expressions in a class’s or data type’s annotation to the corresponding validation delegate. Built-in support has also been added to the base validator implementation (EObjectValidator) so that delegation of expression evaluation also takes place for non-generated models, in a fashion similar to the previously existing support for dynamic validation of data type restrictions. With these changes, modelers are now able to define and evaluate the behaviors of constraints, either statically or dynamically, without having to alter a single line of code.

Milestone 1

This milestone was completed on Friday August 21, 2009.

Fully Overrideable Header Comments in Generated Code

The default header comment generated at the top of all Java, properties, and XML files is now fully overrideable via the GenModel. Previously, the header templates included a $Id$ CVS tag that was always included, whether or not copyright text was manually specified in the GenModel. Users not using CVS, or wanting to generate different (or no) CVS tags into their code, were forced to use dynamic templates.

The header templates have now been modified so that this tag is only generated by default, in the case where no custom copyright text is specified. Users who specify custom copyright text and wish to include this tag should add it to their copyright text.

EMFCopyrightText.png

Not that, in merging, any changes to the header comment resulting from regeneration are ignored. This has always allowed users to modify the header comment manually and regenerate without losing their changes. As a result, existing files, whether regenerated with or without copyright text specified, are not affected by this change.