EMF/New and Noteworthy/Helios

From Eclipsepedia

Jump to: navigation, search

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

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

Contents

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.

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 3

Milestone 4

Support for Feature Setting Delegates

EMF previously supported computation of features, defined as methods and implemented in Java, via an API that is invoked at important moments by an application. In order to delegate computation of a feature’s value to an external engine, the framework was enhanced by exposing the previously existing concept of a setting delegate, based on a well-defined interface.

Defining a Setting Delegate

The contract between a computation consumer (an application) and provider (an external expression engine) is governed by a previously existing interface, SettingDelegate, defined as an inner member of the existing EStructuralFeature interface.

SettingDelegate.png

Classes that implement this interface define methods that call out to the desired external engine to interpret the annotation on a structural feature (perhaps containing an embedded expression) based on the instance value (passed as an argument) and return a result. A basic setting delegate implementation, with stateful and stateless variants, is provided.

Example

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

OCLSettingDelegate.png

It is the responsibility of the setting delegate implementation to handle runtime exceptions and to process computation failures, perhaps by logging an appropriate message.

Defining a Setting Delegate Factory

A factory, following the familiar pattern for similar factories in EMF, provides the means by which feature setting delegates can be instantiated. The interface for this factory is defined as an inner member of the SettingDelegate interface, described above.

SettingDelegateFactory.png

A feature setting delegate is instantiated via the factory upon detection of an annotation (whose source matches the URI for one of the setting delegates referenced by an annotation on the containing class’s owning Ecore package — see below for details) on the metadata for a given structural feature and cached for subsequent retrieval. In this way, the overhead required to look up a setting delegate (based on a URI) and interpret the associated annotation is incurred only once per feature.

Example

A factory for the OCL setting delegate described above might be implemented as shown below.

OCLSettingDelegateFactory.png

Registering a Setting Delegate Factory

A registry, following the familiar pattern for similar registries in EMF, provides the means by which feature setting delegate factories can be discovered. The interface for this registry is defined as an inner member of the setting delegate Factory interface, described above.

SettingDelegateFactoryRegistry.png

As with other EMF registries, an extension point is defined for a global setting delegate factory registry. Thus, it is possible to register setting delegate factories 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 setting delegate factory instance directly to the registry).

Example

The setting delegate factory implemented for OCL might be registered statically with the global registry as shown below.

StaticOCLSettingDelegateFactoryRegistration.png

Alternatively, the setting delegate factory could be registered programmatically with the registry as shown below.

DynamicOCLSettingDelegateFactoryRegistration.png

Referencing a Setting Delegate Factory

In order to use a setting delegate in a particular Ecore model, its factory has to be referenced in an annotation on the package owning the classes on which the features 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 “settingDelegates”. Note that the details key is plural because it will be possible to reference multiple setting delegate factory URIs, each separated by a space, in the value for the key.

Example

The setting delegate factory for OCL expressions, as defined above, could be referenced from a model as shown below.

OCLSettingDelegateFactoryReference.png

Defining the Value of a Feature

Previously, EMF’s support for features amounted to generated methods (or stubs on Java classes which must be implemented by hand). Once a setting delegate has been implemented, registered, and referenced from an Ecore package, however, it is now possible to define and compute the value of a feature in a language other than Java (i.e., the language supported by the setting delegate).

In order for the value of a feature to be defined in an arbitrary language (supported by a setting delegate), it has to be specified, either directly or indirectly, via an annotation on the Ecore structural feature. The source for the annotation has to match the URI for one of the setting delegates referenced by the containing class’s owning Ecore package. The expected content of the annotation’s details (if any) is prescribed by the given setting delegate, but in the case of OCL, for example, a details entry would likely be required, with a key of “derivation” and a value which would be a string expression that can be interpreted by the referenced (OCL) setting delegate. Because the format of the annotation details map (if used at all) is essentially left to the setting delegate, it is conceivable that an expression describing the feature’s value could actually exist in a location other than the annotation itself (e.g., in a file on the file system), identifiable using information in the annotation details.

Example

The value of a feature which computes the reporting chain for an employee could be defined as an OCL expression in an annotation as shown below.

DelegatedOCLSetting.png

Computing the Value of a Feature

Once the value of a feature has been defined, it can be computed 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 interpret expressions on dynamic models. The default code that is produced by the EMF code generator has been altered to delegate computation of a feature’s value, based on information the Ecore structural feature’s annotation, to the corresponding setting delegate. Built-in support has also been added to the EMF runtime so that delegation of value computation also takes place for non-generated models. With these changes, modelers are now able to define and compute the values of features, either statically or dynamically, without having to alter a single line of code.

Support for Operation Invocation Delegates

EMF currently supports execution of operations, defined as methods and implemented in Java, via an API that is invoked at important moments by an application. In order to delegate execution of an operation’s behavior to an external engine, the framework has been enhanced by introducing the concept of an invocation delegate, based on a well-defined interface.

Defining an Invocation Delegate

The contract between an invocation consumer (an application) and provider (an external expression engine) is governed by a new interface, InvocationDelegate, defined as an inner member of the existing EOperation interface.

InvocationDelegate.png

Classes that implement this interface define a method that calls out to the desired external engine to interpret the annotation on an operation (perhaps containing an embedded expression) based on the instance value (passed as an argument) and return a result. A basic invocation delegate implementation, which handles invocation of operations defined on the EObject class, has been provided.

Example

An invocation delegate for OCL expressions might be implemented as shown below.

OCLInvocationDelegate.png

It is the responsibility of the invocation delegate implementation to handle runtime exceptions and to process execution failures, perhaps by logging an appropriate message.

Defining an Invocation Delegate Factory

A factory, following the familiar pattern for similar factories in EMF, provides the means by which operation invocation delegates can be instantiated. The interface for this factory is defined as an inner member of the InvocationDelegate interface, described above.

InvocationDelegateFactory.png

An operation invocation delegate is instantiated via the factory upon detection of an annotation (whose source matches the URI for one of the invocation delegates referenced by an annotation on the containing class’s owning Ecore package — see below for details) on the metadata for a given operation and cached for subsequent retrieval. In this way, the overhead required to look up an invocation delegate (based on a URI) and interpret the associated annotation is incurred only once per operation.

Example

A factory for the OCL invocation delegate described above might be implemented as shown below.

OCLInvocationDelegateFactory.png

Registering an Invocation Delegate

A registry, following the familiar pattern for similar registries in EMF, provides the means by which operation invocation delegate factories can be discovered. The interface for this registry is defined as an inner member of the invocation delegate Factory interface, described above.

InvocationDelegateFactoryRegistry.png

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

Example

The invocation delegate factory implemented for OCL might be registered statically with the global registry as shown below.

StaticOCLInvocationDelegateFactoryRegistration.png

Alternatively, the invocation delegate factory could be registered programmatically with the registry as shown below.

DynamicOCLInvocationDelegateFactoryRegistration.png

Referencing an Invocation Delegate Factory

In order to use an invocation delegate in a particular Ecore model, its factory has to be referenced in an annotation on the package owning the classes on which the operations 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 “invocationDelegates”. Note that the details key is plural because it is possible to reference multiple invocation delegate factory URIs, each separated by a space, in the value for the key.

Example

The invocation delegate factory for OCL expressions, as defined above, could be referenced from a model as shown below.

OCLInvocationDelegateFactoryReference.png

Defining the Behavior of an Operation

Previously, EMF’s support for operations amounted to generated method stubs on Java classes which must be implemented by hand. Once an invocation delegate has been implemented, registered, and referenced from an Ecore package, however, it is now possible to define and execute the behavior of an operation in a language other than Java (i.e., the language supported by the invocation delegate).

In order for the behavior of an operation to be defined in an arbitrary language (supported by an invocation delegate), it has to be specified, either directly or indirectly, via an annotation on the Ecore operation. The source for the annotation has to match the URI for one of the invocation delegates referenced by the containing class’s owning Ecore package. The expected content of the annotation’s details (if any) is prescribed by the given invocation delegate, but in the case of OCL, for example, a details entry would likely be required, with a key of “body” and a value which would be a string expression that can be interpreted by the referenced (OCL) invocation delegate. Because the format of the annotation details map (if used at all) is essentially left to the invocation delegate, it is conceivable that an expression describing the operation’s behavior could actually exist in a location other than the annotation itself (e.g., in a file on the file system), identifiable using information in the annotation details.

Example

The behavior of an operation which determines whether an employee reports to a given manager could be defined as an OCL expression in an annotation as shown below.

DelegatedOCLInvocation.png

Executing the Behavior of an Operation

Once the behavior of an operation has been defined, it can be computed 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 interpret expressions on dynamic models. The default code that is produced by the EMF code generator has been altered to delegate execution of an operation’s behavior, based on information the Ecore operation’s annotation, to the corresponding invocation delegate. Built-in support has also been added to the EMF runtime so that delegation of behavior execution also takes place for non-generated models. This includes a new reflective API for dynamically invoking operations as well as the addition of support for operation identifiers and literals as part of a package’s metadata, similar to the identifiers and literals that were previously defined only for features. Generation of code to support this reflective API in static models is governed by a new 'Operation Reflection' generator model option. With these changes, modelers are now able to define and execute the behaviors of operations, either statically or dynamically, without having to alter a single line of code.

Milestone 5

Milestone 6

Support for Rich Ajax Platform (RAP)

EMF has been enhanced to provide a way for the core EMF runtime UI plug-ins, and generated sample RCP applications that depend on them, to be used with RAP. The non-UI components of EMF, and generated model/edit plug-ins that use them, already worked on RAP (Rich Ajax Platform) out of the box. However, editor plug-ins generated with EMF, and the core runtime UI plug-ins from EMF they depend on, had to be modified in order to use them with RAP.

To support RAP, we introduced new RAP-specific versions of the EMF runtime UI plug-ins, namely org.eclipse.emf.rap.common.ui and org.eclipse.emf.rap.edit.ui. These new plug-ins are included in new features which are in turn referenced by a new "SDK" that's been introduced for use in developing RAP-based application. It's important to note that, like the RAP runtime itself, these new features are not intended for use within a development environment (IDE); rather, they are intended for inclusion in runtime target against RAP-based applications are run.

Defining a Runtime Target for RAP and EMF

The easiest way to set up a runtime target that supports RAP and EMF is to create a new PDE target platform based on the update sites for RAP and EMF. To do so, follow these steps:

1. Select the Plug-in Development > Target Platform category from the Preferences window in Eclipse and press the Add... button.

Preferences.png

2. Choose the option to start with an empty target definition and press the Next > button.

NewTargetDefinition.png

3. Give the new target a name and press the Add... button.

4. Select Software Site as a source and press the Next > button.

AddContent.png

5. Choose to work with the update site for the RAP runtime, i.e., http://download.eclipse.org/rt/rap/1.3/runtime. if it's not already in your list of available update sites, you'll need to add it first. Choose the Rich Ajax Platform (Platform) Runtime SDK feature from the list, ensure that the 'Include required software' option is NOT checked, and press the Finish button.

AddRAPSoftwareSite.png

6. Press the Add... button to add another software site, this time choosing the EMF update site (http://download.eclipse.org/modeling/emf/emf/updates/2.6milestones) and the EMF RAP - Eclipse Modeling Framework SDK for the Rich Ajax Platform feature.

AddEMFSoftwareSite.png

7. Press Finish in the New Target Definition window, select the new runtime target as the active target definition, and press the OK button in the preferences window.

Generating a Sample EMF-based RAP Application

To generate a sample RAP application using EMF, simply choose the new 'Rich Ajax Platform' generator model option and generate your code. Of course, you'll need to have the (normal) EMF SDK installed into your IDE.

RichAjaxPlatform.png

If you take a look at the results, you'll see that the bundle manifest has been set up for "single-sourcing" by using package imports instead of required bundles. This way, the same editor application can actually be used with either an RCP or a RAP target without having to change the code.

Import-Package.png

Running a Sample EMF-based RAP Application

Once you've generated your application to target RAP, running it is a snap if you have the RAP tooling (available via http://download.eclipse.org/rt/rap/1.3/tooling) installed in your IDE. Simply create a run configuration of type 'RAP Application', specify its name, and enter the name of the editor application extension (which should correspond with what's in your editor plug-in's manifest) as the entry point.

RunConfigurations.png

When you run the application, you'll see an embedded browser open automatically.

Library.png