What do you think the
E in
EMF really stands for? Of course, officially it stands for Eclipse, but given how useful the framework is, even independently of Eclipse, folks often question whether it should stand for something else. I'm sure many of you have heard suggestions that it should instead be
"Ed" (because, after all, it is Ed's framework, isn't it?) or perhaps "Excellent" (despite some
beliefs to the contrary).
Given the nature of enhancements that have been made over the past few years, and in light of more recent efforts to port the runtime to other platforms, like GWT and Android, I've come to think EMF should stand for
Extensible Modeling Framework. Indeed, as of the recent M4 milestone of the Helios release, EMF is even more extensible, thanks to investments from two of my other clients. I worked with
NexJ Systems to add support for delegation of constraint and invariant evaluation and with
eXXcellent solutions to introduce similar delegation mechanisms for feature settings and operation invocation.
Validation Delegates
The core validation framework in EMF previously provided a way to declare invariants and constraints on EMF-based implementations using annotated Ecore models. From the perspective of this mechanism, a
constraint is a statement that must be valid at some point in time, whereas an
invariant is an assertion that must always be true. However, one limitation of this mechanism was that invariants and constraints had to be implemented, by hand, in Java source code; there was no means of specifying the behavior of invariants or constraints in an alternative format (such as expressions in some language), nor was there a way to delegate their execution to an external mechanism (such as an expression evaluation engine). With this
enhancement, the core EMF validation framework allows the behavior of invariants and constraints to be defined via additional annotations on Ecore models, and for them to be executed, both from generated code and from dynamic models, via registered external expression engines.
Execution of validation expressions can now be delegated to external expression engines via validation delegates. A validation delegate is a class that implements an interface defining methods that can be called by a validator to perform validation, i.e., evaluate constraints and invariants. Validation delegates can be registered against specific URIs in a registry which can then be queried by validators when performing validation. A global registry of validation delegates, which can be populated via an extension or programmatically via Java code, exists, but it is also possible to create new registries for use in specific contexts, e.g., in cases where it is desirable to override the default (global) validation delegate for a given URI during a particular diagnosis. In order to use a registered validation delegate within a given package, it needs to be declared as a value in an annotation details entry on the package.
An invariant is implemented as a method on a class, defined on the model, and is considered a “stronger” statement about validity than a constraint. The behavior of an invariant can now be defined as a string expression in the details entry value of an annotation on the Ecore operation representing the invariant. In order to delegate evaluation of the expression to a registered validation delegate, the URI for this annotation needs to match one of the values in the details entry of an annotation on the nearest Ecore package. Evaluation of a properly annotated invariant is delegated to the corresponding registered delegate by a validator during a validation operation either statically (via generated code) or dynamically (via reflection) on a model instance.
A constraint is implemented as a method on an external validator class, not on the model itself, and is considered a “weaker” statements about validity than an invariant. The behavior of a constraint can now be defined as a string expression in the details entry value of an annotation on the Ecore class or data type for which the constraint is defined. In order to delegate evaluation of the expression to a registered validation delegate, the URI for this annotation needs to match one of the values in the details entry of an annotation on the nearest Ecore package. Evaluation of a properly annotated constraint is delegated to the corresponding registered delegate by a validator during a validation operation either statically (via generated code) or dynamically (via reflection) on a model instance.
Feature Setting Delegates
EMF previously provided a way to declare that features in EMF-based implementations are
derived via metadata in Ecore models. From the perspective of EMF, a derived feature is a feature whose value is to be computed from other, related data. However, the computation of derived features had to be implemented, by hand, in Java source code; furthermore, there was no means of specifying the values of features (derived or not) in an alternative format (such as expressions in some language), nor was there a way to delegate their computation to an external mechanism (such as an expression engine). With this
enhancement, EMF allows the values of features to be defined via additional annotations on Ecore models, and for them to be computed, both from generated code and from dynamic models, via registered external expression engines.
Computation of features can now be delegated to external expression engines via setting delegates. A setting delegate is a class that implements an interface defining methods that are called by the EMF runtime to access the feature’s value. Setting delegates can be registered against specific URIs in a registry which can then be queried when accessing the values of features. A global registry of setting delegates exists, which can be populated via an extension or programmatically via Java code. In order to use a registered setting delegate within a given package, it needs to be referenced as a value in an annotation details entry on the Ecore package.
The computation of a feature can now be defined via an annotation on the Ecore structural feature. In order to delegate computation of the feature’s value to a registered setting delegate, the URI for this annotation needs to match one of the values in the details entry of an annotation on the containing class’s owning Ecore package. Evaluation of a properly annotated structural feature is delegated to the corresponding registered delegate when the feature’s value is accessed, either statically (via generated code) or dynamically (via reflection) on a model instance.
Operation Invocation Delegates
EMF previously provided a way to declare operations in EMF-based implementations via metadata in Ecore models. From the perspective of EMF, an
operation is a behavioral feature whose specification is beyond the scope of the framework. Although a mechanism already existed to specify the bodies of operations, in Java syntax, via annotations, the behaviors of operations generally had to be implemented by hand, in Java source code; there was no means of specifying the behaviors of operations in an alternative format (such as expressions in some language), nor was there a way to delegate their execution to an external mechanism (such as an expression evaluation engine). With this
enhancement, EMF allows the behaviors of operations to be defined via additional annotations on Ecore models, and for them to be executed, both from generated code and from dynamic models, via registered external expression engines.
Execution of operations can now be delegated to external expression engines via invocation delegates. An invocation delegate is a class that implements an interface defining a method that is called by the EMF runtime to execute the operation’s behavior. Invocation delegates can be registered against specific URIs in a registry which can then be queried when executing the behaviors of operations. A global registry of invocation delegates exists, which can be populated via an extension or programmatically via Java code. In order to use a registered invocation delegate within a given package, it needs to be referenced as a value in an annotation details entry on the Ecore package.
The behavior of an operation can now be defined via an annotation on the Ecore operation. In order to delegate execution of the operation’s behavior to a registered invocation delegate, the URI for this annotation needs to match one of the values in the details entry of an annotation on the containing class’s owning Ecore package. Execution of a properly annotated operation is delegated to the corresponding registered delegate when the operation’s behavior is invoked, either statically (via generated code) or dynamically (via reflection) on a model instance.
Details of these and other enhancements being made to EMF for the Helios release can be found on the project's
New and Noteworthy page. I'll also be covering the new extensibility mechanisms described above as part of a
proposed tutorial at
EclipseCon 2010 (assuming the submission is accepted). Hope to see you there!