Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
EMF/New and Noteworthy/Helios
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
- 1 Milestone 1
- 2 Milestone 2
- 2.1 Support for Validation Delegates
- 2.1.1 Defining a Validation Delegate
- 2.1.2 Registering a Validation Delegate
- 2.1.3 Referencing a Validation Delegate
- 2.1.4 Overriding a Validation Delegate
- 2.1.5 Defining the Behavior of an Invariant
- 2.1.6 Evaluating an Invariant
- 2.1.7 Defining the Behavior of Constraints
- 2.1.8 Evaluating Constraints
- 2.1 Support for Validation Delegates
- 3 Milestone 3
- 4 Milestone 4
- 5 Milestone 5
- 6 Milestone 6
- 7 Milestone 7
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.
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.
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.
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.
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.
Alternatively, the validation delegate could be registered programmatically with the default registry as shown below.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Alternatively, the setting delegate factory could be registered programmatically with the registry as shown below.
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.
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.
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.
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.
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.
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.
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.
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.
Alternatively, the invocation delegate factory could be registered programmatically with the registry as shown below.
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.
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.
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.
2. Choose the option to start with an empty target definition and press the Next > button.
3. Give the new target a name and press the Add... button.
4. Select Software Site as a source and press the Next > button.
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.
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.
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.
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.
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.
When you run the application, you'll see an embedded browser open automatically.
Milestone 7
Support for Google Web Toolkit (GWT)
EMF has been enhanced to provide a way for the core EMF model and edit runtime plug-ins, and generated model and edit plug-ins that depend on them, to be used with GWT. To support GWT, we introduced new GWT-specific versions of certain EMF runtime plug-ins, namely org.eclipse.emf.gwt.common, org.eclipse.emf.gwt.ecore, org.eclipse.emf.gwt.ecore.change, org.eclipse.emf.gwt.ecore.edit, and org.eclipse.emf.gwt.edit. These new plug-ins are currently only available in CVS.
Getting Started with EMF and GWT
To get started building EMF-based applications for GWT, follow these steps:
1. Download the latest Eclipse SDK from http://download.eclipse.org/eclipse/downloads/drops/S-3.6M7-201004291549/index.php.
2. Install the Google plug-in for Eclipse 3.6 by following the instructions at http://code.google.com/eclipse/docs/install-from-zip.html.
3. Download the latest Google Web Toolkit SDK (from http://code.google.com/webtoolkit/download.html) and register it with Eclipse via the Google > Web Toolkit preferences page.
4. Install the latest milestone build of EMF from the site at http://download.eclipse.org/modeling/emf/emf/updates/2.6milestones.
5. Check the EMF GWT runtime projects out of CVS by importing (File > Import... > Team > Team Project Set) the project set file at http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org.eclipse.emf/psf/emf-GWT-Working-Set.psf?root=Modeling_Project&view=co.
6. Create a new EMF Project based on your model, and select GWT for the Runtime Platform generator model option.
7. Select None for the Resource Type generator package option.
8. Generate the model and edit code, by invoking Generator > Generate Model Code and Generator > Generate Edit Code, respectively.