Difference between revisions of "OCL/FAQ"

From Eclipsepedia

< OCL
Jump to: navigation, search
(How do I workaround org.eclipse.emf.ocl deprecation in Helios and later?)
(Extended OCL Standard Library)
(36 intermediate revisions by 2 users not shown)
Line 5: Line 5:
 
== Newbie / General ==
 
== Newbie / General ==
  
Questions in this section are directed at those that are new to the MDT OCL component and are interested in finding out how to begin working with it.
+
Questions in this section are directed at those that are new to the Eclipse OCL component and are interested in finding out how to begin working with it.
  
=== What is MDT OCL? ===
+
=== What is the difference between MDT/OCL and Eclipse OCL? ===
  
MDT OCL provides a parser and interpreter for OCL constraints and
+
None. Prior to the Kepler release, the internal organisation at Eclipse involved an MDT container project, and so Eclipse OCL and Eclipse UML2
 +
were frequently referred to as MDT/OCL and MDT/UML2 respectively.
 +
 
 +
=== What is the difference between Dresden OCL and Eclipse OCL? ===
 +
 
 +
Dresden OCL and Eclipse OCL are independent Open Source developments by independent teams. There is little commonality beyond best endeavours to comply with the OCL specification and exploitation of EMF as the underlying modeling infrastructure.
 +
 
 +
=== What is Eclipse OCL? ===
 +
 
 +
Eclipse OCL provides a parser and interpreter for OCL constraints and
 
expressions on any [[Eclipse Modeling Framework|EMF]]-based metamodel.  By that is meant any
 
expressions on any [[Eclipse Modeling Framework|EMF]]-based metamodel.  By that is meant any
 
metamodel whose meta-metamodel is Ecore, and which (in being a metamodel)
 
metamodel whose meta-metamodel is Ecore, and which (in being a metamodel)
Line 15: Line 24:
 
implementation.
 
implementation.
  
So far, the Eclipse Modeling Project has two such metamodels:  Ecore and UML
+
Traditionally, the Eclipse Modeling Project has two such metamodels:  Ecore and UML
 
(Ecore being its own meta-metamodel).  Hence, the OCL component provides an
 
(Ecore being its own meta-metamodel).  Hence, the OCL component provides an
 
OCL binding for each of these metamodels.  OCL can parse constraints in
 
OCL binding for each of these metamodels.  OCL can parse constraints in
 
either Ecore or [[MDT-UML2|UML]] models, and can evaluate them on the instances of Java
 
either Ecore or [[MDT-UML2|UML]] models, and can evaluate them on the instances of Java
 
classes generated from these models.
 
classes generated from these models.
 +
 +
In the examples plugins, a new Pivot metamodel is used to support Editors and direct Java Code Generation.
  
 
In terms of the OMG's modeling "stack", then, we have in the Eclipse
 
In terms of the OMG's modeling "stack", then, we have in the Eclipse
Line 43: Line 54:
 
The OCL Abstract Syntax Model is, itself, actually a metamodel sitting at the M2 level.
 
The OCL Abstract Syntax Model is, itself, actually a metamodel sitting at the M2 level.
  
=== What is MDT OCL 3.0 update site URL? ===
+
The use of Mn levels can be confusing, since OCL just evaluates expressions on instances, so if your instances are not at M0, your other levels are correspondingly adjusted.
 +
 
 +
====Pivot metamodel====
 +
The Pivot metamodel is a merge of the OCL metamodel with parts of the UML meta-model. This enables an OMG-compliant metamodel to be used.
 +
 
 +
In terms of the OMG's modeling "stack", then, we have in the Eclipse
 +
Modeling Project
 +
{| border="1"
 +
|+ align="bottom"|OCL's relation to the OMG modeling stack
 +
|-
 +
!Modeling Level!!Artifacts!!OCL's Role
 +
|-
 +
|M3||Pivot||This is the metamodel for the OCL Abstract Syntax Model
 +
|-
 +
|M2||Pivot||OCL's generic AST model binds to these metamodels
 +
|-valign="top"
 +
|rowspan="2"| M1 ||*.ecore, *.uml, *.ocl models||rowspan="2"|OCL parses constraints on these models
 +
|-
 +
|generated Java code
 +
|-valign="top"
 +
|rowspan="2"| M0 ||instances of generated Java classes||rowspan="2"| OCL evaluates constraints on these objects
 +
|-
 +
|dynamic EMF objects
 +
|}
 +
 
 +
=== What is Eclipse OCL 3.0 update site URL? ===
  
 
http://download.eclipse.org/modeling/mdt/ocl/3_0/updates/releases/
 
http://download.eclipse.org/modeling/mdt/ocl/3_0/updates/releases/
  
=== Does OCL 1.x work with J2SE 1.4? ===
+
Eclipse OCL Repositories and Updates for Milestone, Interim and Nightly builds are described in [[OCL/Dev/Releng/P2_Repositories_Organization | P2 Repositories Organization]].
 +
 
 +
=== How do I learn OCL? ===
 +
 
 +
[http://books.google.co.uk/books/about/The_object_constraint_language.html?id=gu_6L_hVIfEC&redir_esc=y The object constraint language: getting your models ready for MDA], by Jos B. Warmer, Anneke G. Kleppe is very readable and thoroughly recommended.
 +
 
 +
Clause 7 of the [http://www.omg.org/spec/OCL/2.3.1/PDF OMG specification] is surprisingly readable.
 +
 
 +
You can Google "OCL Tutorial" for many online alternatives.
 +
 
 +
=== Does Eclipse OCL work with J2SE 1.4? ===
  
Because OCL extends EMF's Ecore, OCL's dependencies are the same as those of EMF.
+
Because Eclipse OCL extends EMF's Ecore, OCL's core dependencies are generally the same as those of EMF.
  
<table border="1"><tr><th>OCL</th><th>EMF</th><th>Minimim JVM</th></tr>
+
<table border="1"><tr><th>OCL</th><th>Release</th><th>Minimum JVM</th><th>Platform</th><th>EMF</th><th>UML</th><th>Xtext</th></tr>
  
 
<tr align="center">
 
<tr align="center">
 
<td>1.0</td>
 
<td>1.0</td>
<td>2.2</td>
+
<td>Callisto</td>
 
<td>1.4.2</td>
 
<td>1.4.2</td>
 +
<td>3.2</td>
 +
<td>2.2</td>
 +
<td>2.0</td>
 +
<td></td>
 
</tr>
 
</tr>
  
 
<tr align="center">
 
<tr align="center">
 
<td>1.1</td>
 
<td>1.1</td>
<td>2.3</td>
+
<td>Europa</td>
 
<td>1.5</td>
 
<td>1.5</td>
 +
<td>3.3</td>
 +
<td>2.3</td>
 +
<td>2.1</td>
 +
<td></td>
 
</tr>
 
</tr>
  
 
<tr align="center">
 
<tr align="center">
 
<td>1.2</td>
 
<td>1.2</td>
<td>2.4</td>
+
<td>Ganymede</td>
 
<td>1.5</td>
 
<td>1.5</td>
 +
<td>3.4</td>
 +
<td>2.4</td>
 +
<td>2.2</td>
 +
<td></td>
 
</tr>
 
</tr>
  
 
<tr align="center">
 
<tr align="center">
 
<td>1.3</td>
 
<td>1.3</td>
<td>2.5</td>
+
<td>Galileo</td>
 
<td>1.5</td>
 
<td>1.5</td>
 +
<td>3.5</td>
 +
<td>2.5</td>
 +
<td>3.0</td>
 +
<td></td>
 
</tr>
 
</tr>
  
 
<tr align="center">
 
<tr align="center">
 
<td>3.0</td>
 
<td>3.0</td>
 +
<td>Helios</td>
 +
<td>1.5</td>
 +
<td>3.6</td>
 
<td>2.6</td>
 
<td>2.6</td>
 +
<td>3.1</td>
 +
<td>1.0</td>
 +
</tr>
 +
 +
<tr align="center">
 +
<td>3.1</td>
 +
<td>Indigo</td>
 
<td>1.5</td>
 
<td>1.5</td>
 +
<td>3.7</td>
 +
<td>2.7</td>
 +
<td>3.2</td>
 +
<td>2.0</td>
 +
</tr>
 +
 +
<tr align="center">
 +
<td>4.0</td>
 +
<td>Juno</td>
 +
<td>1.5</td>
 +
<td>3.7 or 3.8 or 4.2</td>
 +
<td>2.7 or 2.8</td>
 +
<td>4.0</td>
 +
<td>2.3 or 2.4</td>
 +
</tr>
 +
 +
<tr align="center">
 +
<td>4.1</td>
 +
<td>Kepler</td>
 +
<td>1.5*</td>
 +
<td>3.7 or 3.8 or 4.2 or 4.3</td>
 +
<td>2.9</td>
 +
<td>4.0 or 4.1</td>
 +
<td>2.4.2</td>
 +
</tr>
 +
 +
<tr align="center">
 +
<td>[4.4]</td>
 +
<td>[Luna]</td>
 +
<td>1.6</td>
 +
<td>3.7 or 3.8 or 4.2 or 4.3 or 4.4</td>
 +
<td>2.9 or 2.10</td>
 +
<td>4.0 or 4.1 or 4.2</td>
 +
<td>2.4.2 or ...</td>
 
</tr>
 
</tr>
  
Line 86: Line 192:
  
 
See also [[EMF/EMF 2.3/JVM Requirements|EMF 2.3 JVM Requirements]].
 
See also [[EMF/EMF 2.3/JVM Requirements|EMF 2.3 JVM Requirements]].
 +
 +
The UML dependencies may be ignored if support for UML models is not required.
 +
 +
The Xtext dependencies may be ignored if the OCL editors are not required.
 +
 +
* Java 1.6 is needed if on the fly compilation of OCL derived Java is required.
 +
 +
Luna dependencies are provisional.
  
 
=== How do I workaround org.eclipse.emf.ocl deprecation in Helios and later? ===
 
=== How do I workaround org.eclipse.emf.ocl deprecation in Helios and later? ===
  
The deprecated org.eclipse.emf.ocl feature and plugin were removed in the MDT/OCL 3.0.0
+
The deprecated org.eclipse.emf.ocl feature and plugin were removed in the Eclipse OCL 3.0.0
 
release. Unfortunately some projects, notably UML2-Tools, continue to reference it. This
 
release. Unfortunately some projects, notably UML2-Tools, continue to reference it. This
prevents their Galileo releases being installed on Helios.
+
prevents their Galileo releases being installed on Helios. A Helios release of UML-Tools
 +
has been built (26-July-2010) but its visibility from
 +
[http://modeling.eclipse.org/modeling/mdt/downloads/index.php?project=uml2tools The UML2-Tools Downloads Page] is
 +
not quite right yet.
  
 
[[https://bugs.eclipse.org/bugs/attachment.cgi?id=173482 Attachment]] to  
 
[[https://bugs.eclipse.org/bugs/attachment.cgi?id=173482 Attachment]] to  
Line 100: Line 217:
 
Therefore to install e.g. UML2-Tools
 
Therefore to install e.g. UML2-Tools
  
* Install MDT/OCL 3.0.0 (most conveniently as part of the Eclipse Modeling Package)
+
* Install Eclipse OCL 3.0.0 (most conveniently as part of the Eclipse Modeling Package)
 
* Download org.eclipse.emf.ocl-update.zip from the [[https://bugs.eclipse.org/bugs/attachment.cgi?id=173482 Attachment]]
 
* Download org.eclipse.emf.ocl-update.zip from the [[https://bugs.eclipse.org/bugs/attachment.cgi?id=173482 Attachment]]
 
* Install New Software from the downloaded org.eclipse.emf.ocl-update.zip
 
* Install New Software from the downloaded org.eclipse.emf.ocl-update.zip
Line 107: Line 224:
  
 
Do not install anything else after UML2-Tools since org.eclipse.emf.ocl-update.zip effectively claims that Galileo and Helios are compatible undermining p2's ability to install consistent plugins.
 
Do not install anything else after UML2-Tools since org.eclipse.emf.ocl-update.zip effectively claims that Galileo and Helios are compatible undermining p2's ability to install consistent plugins.
 +
 +
=== How do I solve: "#" unexpected character ignored ===
 +
 +
In OCL 1.3 a '#' character was used to indicate an enumeration value, and so there are misleading examples such as
 +
 +
  self.allConnections->select(aggregation <#none)->size <= 1
 +
 +
from Section 2.5.3 of UML 1.5 that suggest that # is a prefix for an Enumeration Literal. This syntax was removed in OCL 2.0.
 +
 +
Enumeration Literals should be qualified by their Enumeration name: e.g. AggregationKind::none.
  
 
== OCL Formulation ==
 
== OCL Formulation ==
  
This section answers common problems in the formulation of OCL expressions that achieve some specific aim.  More often than not, these are matters of OCL-the-language, not specific in any way to the MDT implementation.
+
This section answers common problems in the formulation of OCL expressions that achieve some specific aim.  More often than not, these are matters of OCL-the-language, not specific in any way to the Eclipse OCL implementation.
 +
 
 +
=== How do I modify an Object in OCL? ===
 +
 
 +
OCL is a side-effect-free declarative specification language that operates primarily on objects.
 +
 
 +
OCL is almost useless by itself. You have to embed OCL in some context in order to provide the objects on which an OCL expression operates. Thus:
 +
 
 +
* [[OCL/OCLinEcore|OCLinEcore]] embeds OCL in a model to enrich the model with invariants, operations and property initializers.
 +
* [[M2M/Operational_QVT_Language_(QVTO)|QVTo]] embeds OCL in an Imperative language to support model transformation and manipulation
 +
* [[MMT/QVT_Declarative_(QVTd)|QVTc, QVTr]] embed OCL in a Declarative language to support model-to-model transformation
 +
* MOFM2T, [[Acceleo|Acceleo]] embed OCL in a Declarative language to support model-to-text transformation
 +
 
 +
OCL is side-effect free, so OCL cannot change anything and nothing may change while an OCL evaluation is in progress.
 +
 
 +
If you want OCL to change something, you may use OCL to compute a new value or model, but your embedding context is responsible for installing the change.
  
 
=== How do I combine collections of different types? ===
 
=== How do I combine collections of different types? ===
Line 128: Line 270:
 
=== How do I invoke methods such as eContainer(), eContents(), eGet()? ===
 
=== How do I invoke methods such as eContainer(), eContents(), eGet()? ===
  
These methods are EObject methods, so you need to declare that your meta-model extends EObject. Therefore you need to initialize your environment with the following ParsingOption declaration prior to parsing.
+
These methods are EObject methods, so you need to declare that your meta-model extends EObject.  
 +
 
 +
As of the Juno release, there is a Window->Preferences->OCL->Ecore and UML bindings option that allows this to be specified interactively. The final preference is the "Static instance for the implicit-root class option". Select EObject rather than None from the pull-down menu.
 +
 
 +
You can initialize the corresponding option programmatically with the following ParsingOption declaration prior to parsing.
  
 
<pre>
 
<pre>
Line 135: Line 281:
 
     EcorePackage.Literals.EOBJECT);
 
     EcorePackage.Literals.EOBJECT);
 
</pre>
 
</pre>
 +
 +
Otherwise you can just do a cast, assuming that 'http://www.eclipse.org/emf/2002/Ecore' has been imported as 'ecore'.
 +
 +
<pre>
 +
something.oclAsType(ecore::EObject).eClass()
 +
</pre>
 +
  
 
(Prior to EMF 2.5.0M4 this declaration was not necessary if your meta-model explicitly inherited from an Ecore class such as EModelElement or EObject.)
 
(Prior to EMF 2.5.0M4 this declaration was not necessary if your meta-model explicitly inherited from an Ecore class such as EModelElement or EObject.)
 +
 +
The oclContainer() and oclContents() methods have been proposed as the long term solution for the specification gap between OCL, UML and MOF. These methods are available when using the modelled OCL Standard Library that forms part of the Xtext editoir support for the Indigo release.
  
 
=== How do I access unnavigable opposites in Ecore ===
 
=== How do I access unnavigable opposites in Ecore ===
  
In UML, when an association may be drawn with a unidirectional arrow, the association is intended only to be navigated in one direction. It is however permissible for an OCL constraint to navigate in the reverse direction, using an (opposite) role name. The (opposite) role name may be explicitly specified. If the (opposite) role name is omitted, an implicit (opposite) role name is computed from the name of the target class. OCL 2.2 specifies that this name converts the first letter of the target class name to lower case and MDT/OCL 3.0.0 follows this specification.
+
In UML, when an association may be drawn with a unidirectional arrow, the association is intended only to be navigated in one direction. It is however permissible for an OCL constraint to navigate in the reverse direction, using an (opposite) role name. The (opposite) role name may be explicitly specified. If the (opposite) role name is omitted, an implicit (opposite) role name is computed from the name of the target class. OCL 2.2 specifies that this name converts the first letter of the target class name to lower case and Eclipse OCL 3.0.0 follows this specification.
  
(UML specifies that the target class name is used as-is. The OCL specification should change to align with UML and MDT/OCL will change too.)
+
(UML specifies that the target class name is used as-is. The OCL specification should change to align with UML and Eclipse OCL will change too.)
  
When the UML-binding of MDT/OCL is used, navigation of unnavigable opposites works as specified.
+
When the UML-binding of Eclipse OCL is used, navigation of unnavigable opposites works as specified.
  
 
For EMOF meta-models, the OCL specification leaves support for unnavigable opposites as an optional compliance point. It is is difficult for an OCL implementation to support unnavigable opposites since the EMOF meta-model does not provide the required opposite role name. Only the implicit opposite role name could be used. (There are ongoing discussions about introducing a Tag into the EMOF meta-model to persist this information.) It is also difficult for an OCL AST to persist the referredProperty reference to a Property that does not exist.
 
For EMOF meta-models, the OCL specification leaves support for unnavigable opposites as an optional compliance point. It is is difficult for an OCL implementation to support unnavigable opposites since the EMOF meta-model does not provide the required opposite role name. Only the implicit opposite role name could be used. (There are ongoing discussions about introducing a Tag into the EMOF meta-model to persist this information.) It is also difficult for an OCL AST to persist the referredProperty reference to a Property that does not exist.
  
MDT/OCL 3.0.0, when using Ecore meta-models which have similar limitations to EMOF, therefore fails to support unnavigable opposites. However all is not quite lost.
+
Eclipse OCL 3.0.0, when using Ecore meta-models which have similar limitations to EMOF, therefore fails to support unnavigable opposites. However all is not quite lost.
  
 
In [[https://bugs.eclipse.org/229998 Bug 229998]] a solution to the oppositeRoleName persistence problem was introduced using either an Ecore EAnnotation or an EMOF Commented Comment. In [[https://bugs.eclipse.org/251621 Bug 251621]] an additional plugin has been contributed solves the AST problem with an additional OppositePropertyCallExp class. So if you install the extra plug-in and arrange for your Ecore meta-model source to use the EAnnotation, you can use unnavigable opposites.
 
In [[https://bugs.eclipse.org/229998 Bug 229998]] a solution to the oppositeRoleName persistence problem was introduced using either an Ecore EAnnotation or an EMOF Commented Comment. In [[https://bugs.eclipse.org/251621 Bug 251621]] an additional plugin has been contributed solves the AST problem with an additional OppositePropertyCallExp class. So if you install the extra plug-in and arrange for your Ecore meta-model source to use the EAnnotation, you can use unnavigable opposites.
  
It is anticipated that a more integrated solution will be available in MDT/OCL 4.0.0.
+
It is anticipated that a more integrated solution will be available in Eclipse OCL 4.0.0.
  
== OCL Code Generation ==
+
=== How do I add an operation? ===
  
=== How do I generate code from OCL constraints in Ecore? ===
+
==== OCL in Primary Ecore (or UML) ====
  
As of EMF 2.6.0M4 and MDT/OCL 3.0.0M6 EClassifier invariants, EOperation bodies and
+
The easiest way to add an operation is to extend your metamodel directly by adding an EOperation to your Ecore metamodel, putting the operation in the EClass that is most convenient to use as the self context of the operation. The OCLinEcore editor provides an Xtext editor with syntax validation for your OCL contributions to an Ecore metamodel. Alternatively you can edit the generated Java code to provide a Java implementation of your new operation.
EStructuralFeature initial or derived values may be specified using OCL expressions embedded
+
as Ecore annotations within an Ecore meta-model. These expressions may be evaluated either after
+
genmodel has been used to convert your model to Java, or directly using the dynamic
+
capabilities of EMF.
+
  
See [[MDT/OCLinEcore]]
+
Similarly you may add an Operation to the most convenient Class of your UML metamodel. The Papyrus editor provides an Xtext editor with syntax validation for your OCL contributions to a UML metamodel. (More details needed.)
  
=== How do I generate code from OCL constraints in UML? ===
+
==== OCL in Secondary Ecore (or UML) ====
  
See http://www.eclipse.org/modeling/mdt/uml2/docs/presentations/EclipseCon2008_LongTalk_NewFeaturesOfUML2_files/frame.htm.
+
If you are unable to modify your primary metamodels, you may use another metamodel, possibly a specially created metamodel in which you can place your additional operations in some arbitrary class. When you invoke these operations, you will need to use a bogus instance of this class as the self context of the operation. (More details needed.)
  
== OCL Editor ==
+
==== Complete OCL ====
  
=== How do I install an editor for OCL? ===
+
A Complete OCL documnt allows you to add additional operations, properties and constraints to an existing metamodel. These additions are available for use within the Complete OCL document as if they were part of the existing metamodel although the metamodel is not actually modified. The additions cannot therefore be used outside the Complete OCL document. (More details needed.)
  
An editor for OCL has been developed as part of the M2M/QVT Declarative
+
==== Extended OCL Standard Library ====
project. This is being migrated to form part of the MDT/OCL project in the
+
Helios release.
+
  
It is hoped that the relevant Update Sites will facilitate installation soon.
+
If you are using the Pivot version of Eclipse OCL, the OCL Standard Library is fully modelled and extensible. You may therefore define an extended library that imports the standard, or a replacement standard library. In either case you may define additional operations, iterations and properties with a binding to a Java class that implements the appropriate derived LibraryFeature API.
  
To use this editor now follow the following installation steps.
+
The OCL 'Standard' Library is supported using its own own Domain-Specific Language and associated Xtext editor. The built-in OCL Standard Library is compiled by /org.eclipse.ocl.examples.build/src/org/eclipse/ocl/examples/build/GenerateOCLstdlibModel.mwe2 from /org.eclipse.ocl.examples.library/model/OCL-2.5.oclstdlib into /org.eclipse.ocl.examples.pivot/emf-gen/org/eclipse/ocl/examples/pivot/model/OCLstdlib.java. This compiled library is registered with the org.eclipse.ocl.examples.pivot.standard_library extension point for use under the http://www.eclipse.org/ocl/3.1.0/OCL.oclstdlib URI. The default library is normally installed by invoking OCLstdlib.install(). Additional or replacement libraries may be compiled and registered in similar ways.
  
==== Eclipse 3.5 base ====
+
You may reference a custom library from a Complete OCL document using a library import.
  
You require Eclipse 3.5 or later with EMF (Core), EMF Transaction and EMF Validation.
+
<pre>
If you already have these you may skip the install Eclipse step.
+
library 'MyLibrary.oclstdlib'
 +
</pre>
  
Install the Eclipse 3.5 including the modeling packages.
+
 +
Extension libraries may just reference a standard library.
  
Download e.g. http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-modeling-galileo-SR1-incubation-win32.zip and unzip.
+
<pre>
 +
import 'minimal.oclstdlib';
 +
library lib : lib = 'http://minimal.oclstdlib'{
 +
    type OclAny : AnyType {
 +
    operation a(elem : Boolean) : Boolean {
 +
          post a: result = elem;
 +
      }
 +
    }
 +
}
 +
</pre>
  
==== Get OCL Editor Project Set File ====
+
A library operation may be implemented in Java as
  
Start Eclipse, Open the CVS Resource Perspective.
+
<pre>
 +
public static class SpacedOut extends AbstractOperation
 +
{
 +
public static final SpacedOut INSTANCE = new SpacedOut();
  
Create a New Repository Location for
+
@Override
Host: dev.eclipse.org
+
public Object evaluate(@NonNull DomainEvaluator evaluator, @NonNull DomainCallExp callExp,
Repository Path: /cvsroot/modeling
+
@Nullable Object sourceValue, @NonNull Object... argumentValues) {
User: anonymous
+
String string = sourceValue == null? Value.INVALID_NAME : ValuesUtil.oclToString(sourceValue);
Password:
+
return string;
Connection type: pserver
+
}
 +
}
 +
</pre>
  
Select
+
org.eclipse.ocl.examples.domain.library.AbstractOperation requires the most generic varargs arguments. A variety of derived classes such as AbstractBinaryOperation support more restricted arguments. The built-in library operation in  org.eclipse.ocl.examples.domain.library provide many examples of implementations.
  
HEAD/org.eclipse.m2m/org.eclipse.qvt.declarative/plugins/org.eclipse.qvt.declarative.editor.ui/psf
+
A custom library may declare the additional operation and link to its implementaion
 +
 
 +
<pre>
 +
library lib {
 +
type Real : PrimitiveType {
 +
operation spacedOut() : String => 'org.eclipse.ocl.examples.test.xtext.ImportTests$SpacedOut';
 +
}
 +
}
 +
</pre>
 +
 
 +
The custom library has no nsURI of its own so it extends the prevailing standard library. It declares an additional operation for the Real type. The operation is named "spacedOut", takes no arguments and returns a String. The operation name is bound to the the implementation at org.eclipse.ocl.examples.test.xtext.ImportTests$SpacedOut.INSTANCE.
 +
 
 +
See /org.eclipse.ocl.examples.library/model/OCL-2.5.oclstdlib for many examples of operation and iteration declaration and binding to their Java counterparts.
 +
 
 +
Note that library operations may also be implemented in OCL, which can be advantageous when using the code generator where many of the null/invalid possibilities may be pruned by static data flow analysis.
 +
 
 +
<pre>
 +
operation not() : Boolean[?] precedence=UNARY => 'org.eclipse.ocl.examples.library.logical.BooleanNotOperation'
 +
{
 +
body: if self.oclIsInvalid() then self
 +
      else if self = null then null
 +
      else self = false
 +
      endif endif;
 +
}
 +
</pre>
 +
 
 +
==== Java API ====
 +
 
 +
You may add operations and properties directly from Java code. (More details needed.)
 +
 
 +
== Embedded OCL Issues ==
 +
 
 +
This section answers problems that may arise when OCL is used within other tools
 +
 
 +
=== Standalone ===
 +
 
 +
The Eclipse OSGI framework ensure that many important initializations occur automatically. If you are operating in a standalone environment, such as a JUnit test, an MWE script, or an Xtext generated compiler you must orchestrate the initialization manually.
 +
 
 +
==== Unable to find delegate to evaluate the '...' constraint on '...': http://www.eclipse.org/emf/2002/Ecore/OCL ====
 +
 
 +
This error occurs when a validation (or invocation or setting) delegate attempts to activate an OCL delegate but cannot find the required OCL registration.
 +
 
 +
Solution: invoke the following in your startup code:
 +
<pre>
 +
String oclDelegateURI = OCLDelegateDomain.OCL_DELEGATE_URI;
 +
EOperation.Internal.InvocationDelegate.Factory.Registry.INSTANCE.put(oclDelegateURI,
 +
    new OCLInvocationDelegateFactory.Global());
 +
EStructuralFeature.Internal.SettingDelegate.Factory.Registry.INSTANCE.put(oclDelegateURI,
 +
    new OCLSettingDelegateFactory.Global());
 +
EValidator.ValidationDelegate.Registry.INSTANCE.put(oclDelegateURI,
 +
    new OCLValidationDelegateFactory.Global());
 +
</pre>
 +
 
 +
For an Xtext generated compiler, the above code can be placed in YourStandaloneSetup.register().
 +
 
 +
=== Xtext ===
 +
 
 +
==== An object may not circularly contain itself ====
 +
 
 +
This error arises when the root object in a model is validated twice, since validation of the root object marks itself as already validated causing the second validation to report a circular validation.
 +
 
 +
Solution: make sure that registerForImportedPackages is false in your MWE2 editor generation script.
 +
<pre>
 +
fragment = validation.JavaValidatorFragment
 +
{
 +
    registerForImportedPackages = false
 +
}
 +
</pre>
 +
 
 +
== OCL Code Generation ==
 +
 
 +
=== How do I generate code from OCL constraints in Ecore? ===
 +
 
 +
As of EMF 2.6.0M4 and Eclipse OCL 3.0.0M6 EClassifier invariants, EOperation bodies and
 +
EStructuralFeature initial or derived values may be specified using OCL expressions embedded
 +
as Ecore annotations within an Ecore meta-model. These expressions may be evaluated either after
 +
genmodel has been used to convert your model to Java, or directly using the dynamic
 +
capabilities of EMF.
 +
 
 +
See [[OCL/OCLinEcore]]
 +
 
 +
=== How do I generate code from OCL constraints in UML? ===
 +
 
 +
See http://www.eclipse.org/modeling/mdt/uml2/docs/presentations/EclipseCon2008_LongTalk_NewFeaturesOfUML2_files/frame.htm.
 +
 
 +
== OCL Editor ==
 +
 
 +
=== How do I install an editor for OCL? ===
  
and invoke Check Out the psf Folder from the right button menu.
+
==== Eclipse OCL Examples Editors ====
  
==== Import OCL Editor Project Set ====
+
The Eclipse  OCL project provides four Xtext-based editors. Instructions for installation may be found in http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.ocl.doc/tutorials/oclinecore/oclInEcoreTutorial.html.
  
In the Project Explorer
+
The [[OCLinEcore]] editor supports direct maintenance of OCL in an Ecore file, that may be saved as text instead.
  
Select psf/ocl-editor.psf
+
The CompleteOCL editor supports editing OCL documents that complement Ecore meta-models
  
and invoke Import Project Set...
+
The EssentialOCL editor supports editing OCL expressions, probably within another tool.
  
specifying anonymous when asked for a CVS account and passwoes.
+
The OCL Standard Library editor supports editing the extensible library.
  
==== Build OCL Editor Examples ====
+
These editors use a different parser to the Eclipse OCL core and use a modeled OCL standard library, which is slightly closer to the OCL standard. These example editors provide a preview of the fully integrated functionality that should be available in Indigo. Currently none of these editors can generate an AST, which is less of a problem than it might seem. The editors can be used to maintain the textual OCL representation that can then be passed to the OCL facade for parsing and evaluation. This is particularly useful in the OCLinEcore editor where the OCL persistence is textual. However beware that the editors have limited semantic validation and may report different errors to the core LPG parser.
  
Optionally (to make the OCL examples work)
 
  
Select
 
  
org.eclipse.qvt.declarative.examples/buildZips.xml
+
=== OCLinEcore editor fails to initialize due to a missing ModulemapPackage class ===
  
and invoke Run As->Ant Build from the right bitton menu.
+
This problem is caused by the spurious registration of org.eclipse.jst.j2ee.internal.earcreation.modulemap.ModulemapPackage for modulemap.xmi. Since this class does not exist, any code that peruses the EMF Package registry gets a run-time exception that it probably does not handle, so a loop terminates. This occurs when Xtext starts up for OCLinEcore.
  
This should successfully create two OCL zips (refresh the project to see them)
+
For Helios, [https://bugs.eclipse.org/320417 Bug 320417] is registered against WTP, and [https://bugs.eclipse.org/320420 Bug 320420] against Xtext. Both are likely to be fixed in Helios SR1. The workaround for Helios is not to install the JST plugin, typically used by the Web Page editor.
although it will fail when creating further QVTd zips.
+
  
==== Invoke OCL Editor ====
+
== OCL Runtime ==
  
Start a nested Eclipse by selecting some project and invoking
+
=== Stand-alone Tracing ===
Run  As->Eclipse Application.
+
Since the 1.1 release, Eclipse OCL has supported a stand-alone deployment. However, debug tracing has always been an all-or-nothing deal, activated by the org.eclipse.ocl.debug system property. Now, finer-grained control is available using system properties named according to the OCL plug-in's trace options. For example, to trace only evaluation of expressions (not also parsing and other activity), use -Dorg.eclipse.ocl/debug/evaluation=true.
  
To see how the Editor works and get an example configuration
+
=== OCL Thread Safety ===
 +
OCL is side effect free and so concurrent operation in many threads should be possible.
  
Invoke New->Project->Examples->QVT Projects->Royal and Loyal Example
+
However Eclipse OCL exploits EMF and so the [[EMF/FAQ#Is_EMF_thread-safe.3F | EMF Thread Safety]] policies must be considered. Concurrent read and write are not supported between threads and may result in Concurrent Modification Exceptions from iterations or worse. Any code contributed to a call-back takes responsibility for the safety of any changes it makes.
  
Open org.eclipse.qvt.declarative.examples.ocl.royalandloyal/oclsrc/Royal and Loyal/Royal and Loyal.ocl.
+
Note that thread safety is very difficult to test and so the following statements may only be wishful thinking against which Bugzillas can be raised.  
  
==== Create OCL Editor Project ====
+
==== Analysis ====
  
An empty prototype project may be created by
+
Eclipse OCL does not support concurrency during expression analysis, so you may not override any of the parsing methods in order to exploit multiple processors to accelerate parsing. You may however parse multiple expressions concurrently provided you use a distinct OCL Environment for each analysis.
  
Invoke New->Project->Examples->QVT Projects->Empty OCL Project
+
===== Pivot Meta-models =====
  
The important characteristics of this project are that:
+
The Pivot support converts external Ecore/UML/... metamodels to a uniform Pivot representation under control of a MetaModelManager. It is intended to allow the MetaModelManager to be shared by concurrent writers and so avoid the metamodel conversion costs being incurred repeatedly. Distinct OCL environments can share a MetaModelManager.
  
The Java build path specifies 'oclsrc' and 'oclbin' folders.
+
==== Evaluation ====
 +
Eclipse OCL should support multiple concurrent evaluations over shared models, provided no concurrent modification occurs to those models. Eclipse OCL, like EMF, requires the overall application to take responsibility for avoiding concurrency between threads that modify models from those that merely read them.
  
The QVTd Model Registry Nature is set enabling the Model Registry Property Page to
+
===== Ecore Delegates =====
define models that contribute to the OCL 'package' path.
+
Concurrent evaluation requires that all hidden data structures that cache context must be thread safe. This is not necessarily true for the Ecore binding, and so it is recommended that a warm-up of all queries is performed in a single thread before multiple threads are allowed to run concurrently.
  
The QVTd OCL Nature is set enabling compliation of the OCL src to an OCL bin AST.  
+
===== Pivot Delegates =====
 +
Concurrent evaluation requires that all hidden data structures that cache context must be thread safe. This is believed to be true.
  
 +
===== Pivot Code Generation =====
 +
The OCL to Java code generation eliminates the hidden caches for delegate support and instead introduces a number of statically initialized shared constants. These are believed to be thread safe.
  
 +
== UML 2.4 migration ==
  
 +
The Juno (MDT/UML2 4.0, Eclipse OCL 4.0) is aligned with UML 2.4.1 rather than UML 2.2. The following differences may be apparent.
  
 +
* The UML URI is "http://www.eclipse.org/uml2/4.0.0/UML" rather than "http://www.eclipse.org/uml2/3.0.0/UML"
 +
* The UML package name is "UML" rather than "uml"
 +
* The PrimitiveTypes package name is "PrimitiveTypes" rather than "UMLPrimitiveTypes"
 +
* The "Standard.profile.uml" is replaced by "StandardL2.profile.uml" and "StandardL3.profile.uml"
 +
* "UML.metamodel.uml" is the metamodel of the UML metamodel, not of a UML model.
 +
* "UML.merged.uml" is the metamodel of a UML model.
 +
* UML and Ecore types are now distinct: e.g. "pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#String" and "pathmap://UML_LIBRARIES/EcorePrimitiveTypes.library.uml#EString" are no longer identical. Only the EString form avoids a reference to the UML2 Types package from Ecore.
  
 
[[Category:FAQ]]
 
[[Category:FAQ]]
 
[[Category:Modeling]]
 
[[Category:Modeling]]
[[Category:MDT]]
+
[[Category:OCL]]

Revision as of 08:48, 18 September 2013

In addition to the FAQ below, see also the OCL Developer Guide documentation included in the OCL SDK.

Contents


Newbie / General

Questions in this section are directed at those that are new to the Eclipse OCL component and are interested in finding out how to begin working with it.

What is the difference between MDT/OCL and Eclipse OCL?

None. Prior to the Kepler release, the internal organisation at Eclipse involved an MDT container project, and so Eclipse OCL and Eclipse UML2 were frequently referred to as MDT/OCL and MDT/UML2 respectively.

What is the difference between Dresden OCL and Eclipse OCL?

Dresden OCL and Eclipse OCL are independent Open Source developments by independent teams. There is little commonality beyond best endeavours to comply with the OCL specification and exploitation of EMF as the underlying modeling infrastructure.

What is Eclipse OCL?

Eclipse OCL provides a parser and interpreter for OCL constraints and expressions on any EMF-based metamodel. By that is meant any metamodel whose meta-metamodel is Ecore, and which (in being a metamodel) provides an EMF importer to create GenModels that generate a Java implementation.

Traditionally, the Eclipse Modeling Project has two such metamodels: Ecore and UML (Ecore being its own meta-metamodel). Hence, the OCL component provides an OCL binding for each of these metamodels. OCL can parse constraints in either Ecore or UML models, and can evaluate them on the instances of Java classes generated from these models.

In the examples plugins, a new Pivot metamodel is used to support Editors and direct Java Code Generation.

In terms of the OMG's modeling "stack", then, we have in the Eclipse Modeling Project

OCL's relation to the OMG modeling stack
Modeling Level Artifacts OCL's Role
M3 Ecore This is the metamodel for the OCL Abstract Syntax Model
M2 Ecore, UML OCL's generic AST model binds to these metamodels
M1 *.ecore and *.uml models OCL parses constraints on these models
generated Java code
M0 instances of generated Java classes OCL evaluates constraints on these objects
dynamic EMF objects

The OCL Abstract Syntax Model is, itself, actually a metamodel sitting at the M2 level.

The use of Mn levels can be confusing, since OCL just evaluates expressions on instances, so if your instances are not at M0, your other levels are correspondingly adjusted.

Pivot metamodel

The Pivot metamodel is a merge of the OCL metamodel with parts of the UML meta-model. This enables an OMG-compliant metamodel to be used.

In terms of the OMG's modeling "stack", then, we have in the Eclipse Modeling Project

OCL's relation to the OMG modeling stack
Modeling Level Artifacts OCL's Role
M3 Pivot This is the metamodel for the OCL Abstract Syntax Model
M2 Pivot OCL's generic AST model binds to these metamodels
M1 *.ecore, *.uml, *.ocl models OCL parses constraints on these models
generated Java code
M0 instances of generated Java classes OCL evaluates constraints on these objects
dynamic EMF objects

What is Eclipse OCL 3.0 update site URL?

http://download.eclipse.org/modeling/mdt/ocl/3_0/updates/releases/

Eclipse OCL Repositories and Updates for Milestone, Interim and Nightly builds are described in P2 Repositories Organization.

How do I learn OCL?

The object constraint language: getting your models ready for MDA, by Jos B. Warmer, Anneke G. Kleppe is very readable and thoroughly recommended.

Clause 7 of the OMG specification is surprisingly readable.

You can Google "OCL Tutorial" for many online alternatives.

Does Eclipse OCL work with J2SE 1.4?

Because Eclipse OCL extends EMF's Ecore, OCL's core dependencies are generally the same as those of EMF.

OCLReleaseMinimum JVMPlatformEMFUMLXtext
1.0 Callisto 1.4.2 3.2 2.2 2.0
1.1 Europa 1.5 3.3 2.3 2.1
1.2 Ganymede 1.5 3.4 2.4 2.2
1.3 Galileo 1.5 3.5 2.5 3.0
3.0 Helios 1.5 3.6 2.6 3.1 1.0
3.1 Indigo 1.5 3.7 2.7 3.2 2.0
4.0 Juno 1.5 3.7 or 3.8 or 4.2 2.7 or 2.8 4.0 2.3 or 2.4
4.1 Kepler 1.5* 3.7 or 3.8 or 4.2 or 4.3 2.9 4.0 or 4.1 2.4.2
[4.4] [Luna] 1.6 3.7 or 3.8 or 4.2 or 4.3 or 4.4 2.9 or 2.10 4.0 or 4.1 or 4.2 2.4.2 or ...

See also EMF 2.3 JVM Requirements.

The UML dependencies may be ignored if support for UML models is not required.

The Xtext dependencies may be ignored if the OCL editors are not required.

  • Java 1.6 is needed if on the fly compilation of OCL derived Java is required.

Luna dependencies are provisional.

How do I workaround org.eclipse.emf.ocl deprecation in Helios and later?

The deprecated org.eclipse.emf.ocl feature and plugin were removed in the Eclipse OCL 3.0.0 release. Unfortunately some projects, notably UML2-Tools, continue to reference it. This prevents their Galileo releases being installed on Helios. A Helios release of UML-Tools has been built (26-July-2010) but its visibility from The UML2-Tools Downloads Page is not quite right yet.

[Attachment] to [Bug 318941] provides a ZIPped update site containing just enough of org.eclipse.emf.ocl to satisfy the installation requirements of org.eclipse.emf.ocl dependents.

Therefore to install e.g. UML2-Tools

  • Install Eclipse OCL 3.0.0 (most conveniently as part of the Eclipse Modeling Package)
  • Download org.eclipse.emf.ocl-update.zip from the [Attachment]
  • Install New Software from the downloaded org.eclipse.emf.ocl-update.zip
  • Download e.g. mdt-uml2tools-Update-incubation-0.9.0.zip from [UML2-Tools Downloads]
  • Install New Software from the downloaded mdt-uml2tools-Update zip

Do not install anything else after UML2-Tools since org.eclipse.emf.ocl-update.zip effectively claims that Galileo and Helios are compatible undermining p2's ability to install consistent plugins.

How do I solve: "#" unexpected character ignored

In OCL 1.3 a '#' character was used to indicate an enumeration value, and so there are misleading examples such as

 self.allConnections->select(aggregation <#none)->size <= 1

from Section 2.5.3 of UML 1.5 that suggest that # is a prefix for an Enumeration Literal. This syntax was removed in OCL 2.0.

Enumeration Literals should be qualified by their Enumeration name: e.g. AggregationKind::none.

OCL Formulation

This section answers common problems in the formulation of OCL expressions that achieve some specific aim. More often than not, these are matters of OCL-the-language, not specific in any way to the Eclipse OCL implementation.

How do I modify an Object in OCL?

OCL is a side-effect-free declarative specification language that operates primarily on objects.

OCL is almost useless by itself. You have to embed OCL in some context in order to provide the objects on which an OCL expression operates. Thus:

  • OCLinEcore embeds OCL in a model to enrich the model with invariants, operations and property initializers.
  • QVTo embeds OCL in an Imperative language to support model transformation and manipulation
  • QVTc, QVTr embed OCL in a Declarative language to support model-to-model transformation
  • MOFM2T, Acceleo embed OCL in a Declarative language to support model-to-text transformation

OCL is side-effect free, so OCL cannot change anything and nothing may change while an OCL evaluation is in progress.

If you want OCL to change something, you may use OCL to compute a new value or model, but your embedding context is responsible for installing the change.

How do I combine collections of different types?

If you have two or more collections of distinct element types and want to combine them into a single collection, it is not as simple as just unioning them or casting the collections to a common type. In the OCL 2.0 specification, the collection types do not conform to OclAny, so they do not have the oclAsType operation. Also, the semantics of generic type parameters in collections are undefined, so that it is not clear whether, for example, Set(T) has only union(Set(T)) or also union(Set(S)) where S is any supertype of T.

Instead, one must do something like:

-- given types A, B conforming to S but neither of
-- A nor B conforming to the other
context S
def: union(a : Set(A), b : Set(B)) : Set(S) =
    let s : Set(S) = Set{} in s->union(a)->union(b)

which works because Set(S) has an operation union(Set(S)) that accepts arguments of type Set(A) and Set(B) because of the rules of conformance of collection types.

How do I invoke methods such as eContainer(), eContents(), eGet()?

These methods are EObject methods, so you need to declare that your meta-model extends EObject.

As of the Juno release, there is a Window->Preferences->OCL->Ecore and UML bindings option that allows this to be specified interactively. The final preference is the "Static instance for the implicit-root class option". Select EObject rather than None from the pull-down menu.

You can initialize the corresponding option programmatically with the following ParsingOption declaration prior to parsing.

ParsingOptions.setOption(ocl.getEnvironment(),
    ParsingOptions.implicitRootClass(ocl.getEnvironment()),
    EcorePackage.Literals.EOBJECT);

Otherwise you can just do a cast, assuming that 'http://www.eclipse.org/emf/2002/Ecore' has been imported as 'ecore'.

something.oclAsType(ecore::EObject).eClass()


(Prior to EMF 2.5.0M4 this declaration was not necessary if your meta-model explicitly inherited from an Ecore class such as EModelElement or EObject.)

The oclContainer() and oclContents() methods have been proposed as the long term solution for the specification gap between OCL, UML and MOF. These methods are available when using the modelled OCL Standard Library that forms part of the Xtext editoir support for the Indigo release.

How do I access unnavigable opposites in Ecore

In UML, when an association may be drawn with a unidirectional arrow, the association is intended only to be navigated in one direction. It is however permissible for an OCL constraint to navigate in the reverse direction, using an (opposite) role name. The (opposite) role name may be explicitly specified. If the (opposite) role name is omitted, an implicit (opposite) role name is computed from the name of the target class. OCL 2.2 specifies that this name converts the first letter of the target class name to lower case and Eclipse OCL 3.0.0 follows this specification.

(UML specifies that the target class name is used as-is. The OCL specification should change to align with UML and Eclipse OCL will change too.)

When the UML-binding of Eclipse OCL is used, navigation of unnavigable opposites works as specified.

For EMOF meta-models, the OCL specification leaves support for unnavigable opposites as an optional compliance point. It is is difficult for an OCL implementation to support unnavigable opposites since the EMOF meta-model does not provide the required opposite role name. Only the implicit opposite role name could be used. (There are ongoing discussions about introducing a Tag into the EMOF meta-model to persist this information.) It is also difficult for an OCL AST to persist the referredProperty reference to a Property that does not exist.

Eclipse OCL 3.0.0, when using Ecore meta-models which have similar limitations to EMOF, therefore fails to support unnavigable opposites. However all is not quite lost.

In [Bug 229998] a solution to the oppositeRoleName persistence problem was introduced using either an Ecore EAnnotation or an EMOF Commented Comment. In [Bug 251621] an additional plugin has been contributed solves the AST problem with an additional OppositePropertyCallExp class. So if you install the extra plug-in and arrange for your Ecore meta-model source to use the EAnnotation, you can use unnavigable opposites.

It is anticipated that a more integrated solution will be available in Eclipse OCL 4.0.0.

How do I add an operation?

OCL in Primary Ecore (or UML)

The easiest way to add an operation is to extend your metamodel directly by adding an EOperation to your Ecore metamodel, putting the operation in the EClass that is most convenient to use as the self context of the operation. The OCLinEcore editor provides an Xtext editor with syntax validation for your OCL contributions to an Ecore metamodel. Alternatively you can edit the generated Java code to provide a Java implementation of your new operation.

Similarly you may add an Operation to the most convenient Class of your UML metamodel. The Papyrus editor provides an Xtext editor with syntax validation for your OCL contributions to a UML metamodel. (More details needed.)

OCL in Secondary Ecore (or UML)

If you are unable to modify your primary metamodels, you may use another metamodel, possibly a specially created metamodel in which you can place your additional operations in some arbitrary class. When you invoke these operations, you will need to use a bogus instance of this class as the self context of the operation. (More details needed.)

Complete OCL

A Complete OCL documnt allows you to add additional operations, properties and constraints to an existing metamodel. These additions are available for use within the Complete OCL document as if they were part of the existing metamodel although the metamodel is not actually modified. The additions cannot therefore be used outside the Complete OCL document. (More details needed.)

Extended OCL Standard Library

If you are using the Pivot version of Eclipse OCL, the OCL Standard Library is fully modelled and extensible. You may therefore define an extended library that imports the standard, or a replacement standard library. In either case you may define additional operations, iterations and properties with a binding to a Java class that implements the appropriate derived LibraryFeature API.

The OCL 'Standard' Library is supported using its own own Domain-Specific Language and associated Xtext editor. The built-in OCL Standard Library is compiled by /org.eclipse.ocl.examples.build/src/org/eclipse/ocl/examples/build/GenerateOCLstdlibModel.mwe2 from /org.eclipse.ocl.examples.library/model/OCL-2.5.oclstdlib into /org.eclipse.ocl.examples.pivot/emf-gen/org/eclipse/ocl/examples/pivot/model/OCLstdlib.java. This compiled library is registered with the org.eclipse.ocl.examples.pivot.standard_library extension point for use under the http://www.eclipse.org/ocl/3.1.0/OCL.oclstdlib URI. The default library is normally installed by invoking OCLstdlib.install(). Additional or replacement libraries may be compiled and registered in similar ways.

You may reference a custom library from a Complete OCL document using a library import.

library 'MyLibrary.oclstdlib'


Extension libraries may just reference a standard library.

import 'minimal.oclstdlib';
library lib : lib = 'http://minimal.oclstdlib'{
    type OclAny : AnyType {
    	operation a(elem : Boolean) : Boolean {
           post a: result = elem;
       }
    }
}

A library operation may be implemented in Java as

public static class SpacedOut extends AbstractOperation
{
	public static final SpacedOut INSTANCE = new SpacedOut();

	@Override
	public Object evaluate(@NonNull DomainEvaluator evaluator, @NonNull DomainCallExp callExp,
		@Nullable Object sourceValue, @NonNull Object... argumentValues) {
		String string = sourceValue == null? Value.INVALID_NAME : ValuesUtil.oclToString(sourceValue);
		return string;
	}
}

org.eclipse.ocl.examples.domain.library.AbstractOperation requires the most generic varargs arguments. A variety of derived classes such as AbstractBinaryOperation support more restricted arguments. The built-in library operation in org.eclipse.ocl.examples.domain.library provide many examples of implementations.

A custom library may declare the additional operation and link to its implementaion

library lib {
	type Real : PrimitiveType {
		operation spacedOut() : String => 'org.eclipse.ocl.examples.test.xtext.ImportTests$SpacedOut';
	}
}

The custom library has no nsURI of its own so it extends the prevailing standard library. It declares an additional operation for the Real type. The operation is named "spacedOut", takes no arguments and returns a String. The operation name is bound to the the implementation at org.eclipse.ocl.examples.test.xtext.ImportTests$SpacedOut.INSTANCE.

See /org.eclipse.ocl.examples.library/model/OCL-2.5.oclstdlib for many examples of operation and iteration declaration and binding to their Java counterparts.

Note that library operations may also be implemented in OCL, which can be advantageous when using the code generator where many of the null/invalid possibilities may be pruned by static data flow analysis.

operation not() : Boolean[?] precedence=UNARY => 'org.eclipse.ocl.examples.library.logical.BooleanNotOperation'
{
	body: if self.oclIsInvalid() then self
	      else if self = null then null
	      else self = false
	      endif endif;
}

Java API

You may add operations and properties directly from Java code. (More details needed.)

Embedded OCL Issues

This section answers problems that may arise when OCL is used within other tools

Standalone

The Eclipse OSGI framework ensure that many important initializations occur automatically. If you are operating in a standalone environment, such as a JUnit test, an MWE script, or an Xtext generated compiler you must orchestrate the initialization manually.

Unable to find delegate to evaluate the '...' constraint on '...': http://www.eclipse.org/emf/2002/Ecore/OCL

This error occurs when a validation (or invocation or setting) delegate attempts to activate an OCL delegate but cannot find the required OCL registration.

Solution: invoke the following in your startup code:

String oclDelegateURI = OCLDelegateDomain.OCL_DELEGATE_URI;
EOperation.Internal.InvocationDelegate.Factory.Registry.INSTANCE.put(oclDelegateURI,
    new OCLInvocationDelegateFactory.Global());
EStructuralFeature.Internal.SettingDelegate.Factory.Registry.INSTANCE.put(oclDelegateURI,
    new OCLSettingDelegateFactory.Global());
EValidator.ValidationDelegate.Registry.INSTANCE.put(oclDelegateURI,
    new OCLValidationDelegateFactory.Global());

For an Xtext generated compiler, the above code can be placed in YourStandaloneSetup.register().

Xtext

An object may not circularly contain itself

This error arises when the root object in a model is validated twice, since validation of the root object marks itself as already validated causing the second validation to report a circular validation.

Solution: make sure that registerForImportedPackages is false in your MWE2 editor generation script.

fragment = validation.JavaValidatorFragment
{
    registerForImportedPackages = false
}

OCL Code Generation

How do I generate code from OCL constraints in Ecore?

As of EMF 2.6.0M4 and Eclipse OCL 3.0.0M6 EClassifier invariants, EOperation bodies and EStructuralFeature initial or derived values may be specified using OCL expressions embedded as Ecore annotations within an Ecore meta-model. These expressions may be evaluated either after genmodel has been used to convert your model to Java, or directly using the dynamic capabilities of EMF.

See OCL/OCLinEcore

How do I generate code from OCL constraints in UML?

See http://www.eclipse.org/modeling/mdt/uml2/docs/presentations/EclipseCon2008_LongTalk_NewFeaturesOfUML2_files/frame.htm.

OCL Editor

How do I install an editor for OCL?

Eclipse OCL Examples Editors

The Eclipse OCL project provides four Xtext-based editors. Instructions for installation may be found in http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.ocl.doc/tutorials/oclinecore/oclInEcoreTutorial.html.

The OCLinEcore editor supports direct maintenance of OCL in an Ecore file, that may be saved as text instead.

The CompleteOCL editor supports editing OCL documents that complement Ecore meta-models

The EssentialOCL editor supports editing OCL expressions, probably within another tool.

The OCL Standard Library editor supports editing the extensible library.

These editors use a different parser to the Eclipse OCL core and use a modeled OCL standard library, which is slightly closer to the OCL standard. These example editors provide a preview of the fully integrated functionality that should be available in Indigo. Currently none of these editors can generate an AST, which is less of a problem than it might seem. The editors can be used to maintain the textual OCL representation that can then be passed to the OCL facade for parsing and evaluation. This is particularly useful in the OCLinEcore editor where the OCL persistence is textual. However beware that the editors have limited semantic validation and may report different errors to the core LPG parser.


OCLinEcore editor fails to initialize due to a missing ModulemapPackage class

This problem is caused by the spurious registration of org.eclipse.jst.j2ee.internal.earcreation.modulemap.ModulemapPackage for modulemap.xmi. Since this class does not exist, any code that peruses the EMF Package registry gets a run-time exception that it probably does not handle, so a loop terminates. This occurs when Xtext starts up for OCLinEcore.

For Helios, Bug 320417 is registered against WTP, and Bug 320420 against Xtext. Both are likely to be fixed in Helios SR1. The workaround for Helios is not to install the JST plugin, typically used by the Web Page editor.

OCL Runtime

Stand-alone Tracing

Since the 1.1 release, Eclipse OCL has supported a stand-alone deployment. However, debug tracing has always been an all-or-nothing deal, activated by the org.eclipse.ocl.debug system property. Now, finer-grained control is available using system properties named according to the OCL plug-in's trace options. For example, to trace only evaluation of expressions (not also parsing and other activity), use -Dorg.eclipse.ocl/debug/evaluation=true.

OCL Thread Safety

OCL is side effect free and so concurrent operation in many threads should be possible.

However Eclipse OCL exploits EMF and so the EMF Thread Safety policies must be considered. Concurrent read and write are not supported between threads and may result in Concurrent Modification Exceptions from iterations or worse. Any code contributed to a call-back takes responsibility for the safety of any changes it makes.

Note that thread safety is very difficult to test and so the following statements may only be wishful thinking against which Bugzillas can be raised.

Analysis

Eclipse OCL does not support concurrency during expression analysis, so you may not override any of the parsing methods in order to exploit multiple processors to accelerate parsing. You may however parse multiple expressions concurrently provided you use a distinct OCL Environment for each analysis.

Pivot Meta-models

The Pivot support converts external Ecore/UML/... metamodels to a uniform Pivot representation under control of a MetaModelManager. It is intended to allow the MetaModelManager to be shared by concurrent writers and so avoid the metamodel conversion costs being incurred repeatedly. Distinct OCL environments can share a MetaModelManager.

Evaluation

Eclipse OCL should support multiple concurrent evaluations over shared models, provided no concurrent modification occurs to those models. Eclipse OCL, like EMF, requires the overall application to take responsibility for avoiding concurrency between threads that modify models from those that merely read them.

Ecore Delegates

Concurrent evaluation requires that all hidden data structures that cache context must be thread safe. This is not necessarily true for the Ecore binding, and so it is recommended that a warm-up of all queries is performed in a single thread before multiple threads are allowed to run concurrently.

Pivot Delegates

Concurrent evaluation requires that all hidden data structures that cache context must be thread safe. This is believed to be true.

Pivot Code Generation

The OCL to Java code generation eliminates the hidden caches for delegate support and instead introduces a number of statically initialized shared constants. These are believed to be thread safe.

UML 2.4 migration

The Juno (MDT/UML2 4.0, Eclipse OCL 4.0) is aligned with UML 2.4.1 rather than UML 2.2. The following differences may be apparent.

  • The UML URI is "http://www.eclipse.org/uml2/4.0.0/UML" rather than "http://www.eclipse.org/uml2/3.0.0/UML"
  • The UML package name is "UML" rather than "uml"
  • The PrimitiveTypes package name is "PrimitiveTypes" rather than "UMLPrimitiveTypes"
  • The "Standard.profile.uml" is replaced by "StandardL2.profile.uml" and "StandardL3.profile.uml"
  • "UML.metamodel.uml" is the metamodel of the UML metamodel, not of a UML model.
  • "UML.merged.uml" is the metamodel of a UML model.
  • UML and Ecore types are now distinct: e.g. "pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#String" and "pathmap://UML_LIBRARIES/EcorePrimitiveTypes.library.uml#EString" are no longer identical. Only the EString form avoids a reference to the UML2 Types package from Ecore.