This section may be contrasted with the corresponding Parsing Constraints and Queries for the Ecore binding to see examples of the changes needed to migrate from the Ecore binding to the Pivot binding.
The OCL parser provides two APIs for parsing constraint and query expressions using the
class provides both a Facade and a Handle for the various objects that support different aspects of OCL parsing and evaluation.
OCL class is a simple type.
There is no need for the many template parameters that parameterize the equivalent OCL class for the Ecore/UML bindings.
Behind the scenes,
OCL instances share an
EnvironmentFactory that creates and owns the primary support objects and provides an API to create these and other important artefacts.
ProjectManager supports the discovery of metamodels to resolve URI references.
OCL.NO_PROJECTS is a very lightweight
ProjectManager supporting access only to those models known to the external
OCL.CLASS_PATH is a heavyweight
ProjectManager supporting access to models registered with plugins on the Java classpath.
ResourceSet is a potentially user-supplied
ResourceSet to manage the external metamodels such as Ecore or UML models or Xtext Concrete Syntax models.
The external metamodels are converted to the normalized Pivot representation under control of the
MetamodelManager which maintains the normalized representation in an Abstract Syntax as
A merged view of the normalized metamodels is provided by the
CompleteModel under control of the
CompleteEnvironment that also supervises a
LambdaManager for more specialized aspects of the merge. The
CompleteEnvironment API supports synthesis of Collection and Map types.
Access to the normalized representations from diverse contexts, in particular from generated Java code, requires an ability to discover the merged representation of e.g. the
Boolean type from the minimal concept of a
Boolean type-id. The
IdResolver performs the id-to-object conversion.
When Pivot models are derived from Xtext source text, a Concrete Syntax representation is converted to the normalized Abstract Syntax. The
CS2ASMapping tracks the equivalences in this conversion so that tooling can reverse the navigation to discover appropriate text to highlight in a source editor for an underlying model element.
OCL handle may also reference a
ModelManager. This is used to identify objects during evaluation of operations such as
The static factory methods of the
OCL class are used to create new instances. These are suitable for suitable for parsing OCL constraints
on any Ecore or UML model and evaluating them on instances of the model.
If you already have models loaded in a
ResourceSet, you may activate OCL functionality by creating a new
OCL instance specifying that OCL should exploit that ResourceSet.
Alternatively you may leave the
OCL instance to create the
It is good practice to invoke
dispose() explicitly to release all
OCL-related Resource references promptly rather than rely on garbage collection.
When repeated parsing and evaluation occurs on a model, it is very beneficial to re-use rather than
re-create the underyling OCL support objects. This is easily achieved in simple scenarios by re-using the
OCL instance directly. In more complex scenarios the handle behavior of an
OCL instance can be exploited
to create multiple handles for diverse usages each of which is disposed when complete. The dispose of the
underlying OCL support occurs when the final handle disposes.
Parsing an OCL expression requires a classifier to define the type of
self. This is passed to
createInvariant(), which enforces a Boolean result type, or to
createQuery(), which allows any result type.
The result of parsing a query expression or a constraint is an
an instance of the
Abstract Syntax Model.
In the case of constraints on operations or properties, the context consists
of two elements: the constrained operation/property and a classifier that
defines the type of
self while parsing the OCL. The classifier is deduced as the
container of the operation or property. These can be constrained as follows:
The preceding examples are simplified by the assumption that there will be no parsing errors. In practice
ParserExceptions should be caught and handled in an appropriate way by the application.
The Ecore/UML bindings for OCL provide an OCLHelper class to assist in creating queries. A similar class is available with the Pivot binding for compatibility although it is largely redundant since the
OCLclass class be used directly. An
OCLHelperwill give a small performance benefit for multiple parses but not as much as direct use of an underlying
ParserContextor a structuring multiple queries in a Complete OCL document.
From an OCL instance, we can create a helper object with which to parse constraints and additional operation/attribute definitions.
OCLHelperis 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
createInvariant(): convenience for invariant constraints
createPrecondition(): convenience for pre-condition constraints
createPostcondition(): convenience for post-condition constraints
createBodyCondition(): convenience for body conditions
createDerivedValueExpression(): convenience for attribute derived values
Different kinds of constraints require different context environments. The
setAttributeContext()methods create the appropriate nested
Environments in the host
OCLinstance’s root environment.
The Ecore/UML bindings variously produce a Constraint or OCLExpression result. A Constraint has too much context and an OCLExpression too little. An ExpressionInOCL produced by the Pivot binding is just right.