Classic Ecore/UML Programmers Guide

Classic Ecore/UML Programmers Guide

Parsing Constraints and Queries
Evaluating Constraints and Queries
Parsing OCL Documents
OCL Relationship to Metamodels
OCL Abstract Syntax Model
Customizing the Environment
OCL Persistence
Creating Metamodel Bindings
Incrementally Re-Evaluating OCL Expressions Using the Impact Analyzer
Delegates
Ecore/UML Standalone Configuration

The Ecore/UML Programmers Guide describes the ways in which the Ecore or UML bindings of Eclipse OCL can be used from Java programs.

The Ecore binding has been available since Eclipse OCL 1.0.0 (Callisto). The UML binding was added in 1.1.0 (Europa). Both will remain for as long as necessary. Examples quality prototypes of the new UML-aligned Pivot binding were first available in 3.1.0 (Indigo). The Pivot binding will become the preferred binding in 4.2.0 (Luna). The Pivot binding is described in a separate Pivot Programmers Guide.

The OCL Parser/Interpreter provides an implementation of the Object Constraint Language 2.3 specification for EMF-based metamodels and models. It offers OCL constraint and query parsing and evaluation, model-based validation, and provides an infrastructure for content assist in textual editors.

The following features are supported in the current version:

The above constructs are supported by the parser for parsing and for evaluation, with the exception of the oclIsNew() operation and message expressions. All of the above are supported for both Ecore and UML models. The following are supported by default for UML (both in parsing and evaluation):

The following features are provided in addition to the OCL specification:

The OCL implementation is defined in plug-ins for convenient deployment in Eclipse, but as is the case for EMF, it can also be used stand-alone. The plug-ins are partitioned thus:

Please refer to the OCL Interpreter Tutorial for review of the code samples.

Parsing Constraints and Queries

The OCL parser provides two APIs for parsing constraint and query expressions. The OCLHelper interface is designed primarily for parsing constraints and query expressions embedded in models, such as Ecore or UML models. The OCL class serves as the main entrypoint into the parsing API but also implements the parsing of OCL documents, for example from text files. In both cases, the concept of Environment is crucial.

The OCL Environment

The following diagram shows the core of the Environment API, that clients of the OCL parser interact with:

The OCL class is a generic type; its type parameters represent the various metaclasses of the metamodels that OCL works with in the UML/MOF family of OMG specifications. For example, <C> represents the Classifier concept, <O> the Operation concept, etc. See the discussion of metamodels supported by OCL for details of the mappings. The same type parameter names are used consistently throughout the OCL APIs to represent the same metaclasses.

The OCL class defines instances of autonomous OCL parsing and evaluation environments. It has a single root Environment created by an EnvironmentFactory implementation for a particular EMF-based metamodel. The OCL environment consists, conceptually, of the model that is to be constrained together with all of the constraints and additional operations and attributes defined (via OCL) for the purpose of formulating constraints.

Environment s nest. Usually the root environment has no correlation to an element in the model, or it may correspond to some Package providing a default namespace (called a package context). Alternatively, it may contain one or more nested environments defining package namespaces. A package context contains one or more classifier contexts, which in turn can contain operation and/or attribute contexts. Whereas the purpose of a package context is primarily to assist in the look-up of named model elements, the classifier, operation, and attribute contexts have deeper meaning.

A classifier context defines the type of the self variable in OCL constraints and queries. By itself, it is the context for invariant constraints for the context classifier. Additionally, as the parent context for operation and attribute constraints, it indicates the classifier in which context an operation or attribute constraint applies; this may be the classifier that defines these features, or it may inherit them from some more general classifier.

An Environment may contain named Variable s to which OCL expressions can refer. The most common of these is self. Others include the parameters defined by an operation (and its result), in the case of an operation context. The OCL API even allows clients to add variables, in code, to define “global” names.

Creating an OCL Environment

The static factory methods on the OCL class are used to create instances. It is a good practice to re-use the same OCL instance for all parsing and evaluation of constraints and queries on a model while that model is loaded (usually in some ResourceSet in an editor). Using the shared environment factory for the Ecore metamodel, we can create an OCL environment suitable for parsing OCL constraints on any Ecore model and evaluating them on instances of the model:

[Text for cut and paste]

Several of the type parameters in the OCL generic type signature are useful mostly within the OCL API. We leave them, here, as wildcards.

The OCL Helper

From an OCL instance, we can create a helper object with which to parse constraints and additional operation/attribute definitions. This OCLHelper stores all of the instantiations of OCL template metaclasses (such as CollectionType(T) and TupleType and additional operation/attribute definitions in the root environment of the OCL that created it. This ensures that all of these constructs are available for reuse in subsequent parsing.

The OCLHelper is primarily designed for parsing constraints and query expressions embedded in models, providing the following API for that purpose:

  • createQuery(): parses a query expression

  • createConstraint(): parses a constraint of a given ConstraintKind

  • createInvariant(): convenience for invariant constraints

  • createPrecondition(): convenience for pre-condition constraints

  • createPostcondition(): convenience for post-condition constraints

  • createBodyCondition(): convenience for body conditions

  • createInitialValueExpression(): convenience for attribute initial values

  • createDerivedValueExpression(): convenience for attribute derived values

  • defineOperation(): convenience for additional operation definitions

  • defineAttribute(): convenience for additional attribute definitions

Different kinds of constraints require different context environments. The setContext(), setOperationContext(), and setAttributeContext() methods create the appropriate nested Environment@s in the host @OCL instance’s root environment.

The result of parsing a query expression is an OCLExpression , an instance of the Abstract Syntax Model . The result of parsing a constraint is an instance of the Constraint metaclass defined by the OCL's target metamodel .

[Text for cut and paste]

Ecore does not define a Constraint metaclass, so the OCL binding for Ecore supplies one.

Operation and Attribute Contexts

In the case of constraints on operations or attributes, the context consists of two elements: the constrained operation/attribute and a classifier in the context of which the constraint is to apply. This accounts for the possibility that a classifier defines constraints on inherited features. As an example, consider the EModelElement::getEAnnotation(EString) operation and EReference::eReferenceType property in the Ecore metamodel. These can be constrained as follows:

[Text for cut and paste]