Evaluating Constraints and Queries

Evaluating Constraints and Queries

In Parsing Constraints, we saw how to use the OCLHelper API for parsing OCL constraints and query expressions. Parsing constraints is very interesting in itself, but we can also make OCL come alive in our applications by evaluating these constraints. For this, OCL provides a Query API.

The OCL Query

Like the OCLHelper for parsing constraints, the OCL facade object provides Query objects for evaluating constraints and query expressions.

The Query encapsulates an EvaluationEnvironment providing the run-time values of context variables to the OCL interpreter. These context variables are set and retrieved using the following methods:

  • add(String, Object): adds a name-value binding for a variable

  • replace(String, Object): replaces an existing variable binding

  • remove(): removes a variable binding

  • getValueOf(String): obtains a variable value

The context variables of primary interest are self and, in operation constraints, the variables corresponding to its parameters. The EvaluationEnvironment API is also used to supply values for “global” variables added to the parsing Environment by the client.

Another important consideration in the evaluation environment is the allInstances() operation, which obtains the entire extent of a classifier. For data types, this is a simple problem: the extent of an Enumeration is well defined and the extents of other kinds of DataType s are undefined. For Class extents, the EvaluationEnvironment provides support for an extent map, mapping classes to the sets of their instances, as determined by the client. A client sets the extent map using the OCL.setExtentMap() method. The default extent map, if none is provided by the client, lazily computes the extent of a class from the EMF Resource containing the context element of the evaluation. An alternative extent map can be found in org.eclipse.ocl.ecore.opposites.ExtentMap .

So, after optionally setting values of context variables (other than self; the Query takes care of this) and an extent map, simply construct a query and use it to evaluate the expression or check the constraint:

[Text for cut and paste]

One of the advantages of the Query API is that a query’s evaluation environment can be reused for multiple evaluations, as above. The extent of any classifier is only computed once. For convenience, however, in situations where only a single evaluation is required, the OCL class provides shortcuts:

[Text for cut and paste]

The Query API also provides methods that work on multiple elements. The first example, above, could be written more succinctly as:

[Text for cut and paste]