<html> | |
<head> | |
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
<title>Working with Classic OCL</title> | |
<link href="book.css" rel="stylesheet" type="text/css"> | |
<meta content="DocBook XSL Stylesheets V1.75.1" name="generator"> | |
<link rel="home" href="index.html" title="OCL Documentation"> | |
<link rel="up" href="Tutorials.html" title="Tutorials"> | |
<link rel="prev" href="ValidationTutorial.html" title="Validation tutorial"> | |
<link rel="next" href="Extensions.html" title="Extensions (in the Unified/Pivot OCL prototype)"> | |
</head> | |
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> | |
<h1 xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">Working with Classic OCL</h1> | |
<div class="section" title="Working with Classic OCL"> | |
<div class="titlepage"> | |
<div> | |
<div> | |
<h2 class="title" style="clear: both"> | |
<a name="OCLInterpreterTutorial"></a>Working with Classic OCL</h2> | |
</div> | |
</div> | |
</div> | |
<div class="section" title="Overview"> | |
<div class="titlepage"> | |
<div> | |
<div> | |
<h3 class="title"> | |
<a name="Overview4"></a>Overview</h3> | |
</div> | |
</div> | |
</div> | |
<p>This tutorial illustrates the various services provided by the Classic Eclipse OCL | |
implementation.</p> | |
</div> | |
<div class="section" title="References"> | |
<div class="titlepage"> | |
<div> | |
<div> | |
<h3 class="title"> | |
<a name="References3"></a>References</h3> | |
</div> | |
</div> | |
</div> | |
<p>This tutorial assumes that the reader is familiar with the Eclipse extension point | |
architecture. There is an abundance of on-line help in Eclipse for those | |
unfamiliar with extension points.</p> | |
<p>To see the complete source code for the examples shown in this tutorial, install | |
the | |
<a class="link" href="OCLInterpreterExample.html" title="OCL Interpreter Example">OCL Interpreter Example</a> | |
plug-in into your workspace. | |
</p> | |
<p>Other references:</p> | |
<div class="itemizedlist"> | |
<ul class="itemizedlist" type="disc"> | |
<li class="listitem"> | |
<p>For an environment in which to test the OCL expressions that you will create in this tutorial, install the | |
<a class="ulink" href="../references/examples/exampleOverview.html" target="_new">Library Metamodel</a> example. | |
</p> | |
</li> | |
<li class="listitem"> | |
<p> | |
<a class="ulink" href="http://www.omg.org/spec/OCL" target="_new">OCL 2.0</a> specification. | |
</p> | |
</li> | |
</ul> | |
</div> | |
</div> | |
<div class="section" title="Parsing OCL Expressions"> | |
<div class="titlepage"> | |
<div> | |
<div> | |
<h3 class="title"> | |
<a name="ParsingOCLExpressions"></a>Parsing OCL Expressions</h3> | |
</div> | |
</div> | |
</div> | |
<p>The first responsibility of the OCL interpreter is to parse OCL expressions. | |
One of the purposes of parsing an expression is to validate it: if it can be | |
parsed, it is well-formed (the parser automatically validates the expression | |
against the semantic well-formedness rules).</p> | |
<p>The main entrypoint into the OCL API is the | |
<a class="ulink" href="http://download.eclipse.org/ocl/javadoc/6.4.0/org/eclipse/ocl/OCL.html" target="_new">OCL</a> class. An | |
<code class="code">OCL</code> provides an autonomous OCL parsing environment. It tracks all constraints that are parsed in this environment, including the definitions of additional operations and attributes. The | |
<code class="code">OCL.newInstance()</code> factory method is used to create a new OCL with an | |
<code class="code">EnvironmentFactory</code> that provides the binding to a particular metamodel (Ecore or UML). In this tutorial, we will use the Ecore binding. | |
</p> | |
<p>To parse a query expression, we will use the | |
<a class="ulink" href="http://download.eclipse.org/ocl/javadoc/6.4.0/org/eclipse/ocl/helper/OCLHelper.html" target="_new"> | |
<code class="code">OCLHelper</code> | |
</a> object, which provides convenient operations for parsing queries and constraints | |
(intended for processing constraints embedded in models). | |
</p> | |
<div class="literallayout"> | |
<p> | |
<code class="code">boolean valid;<br> | |
OCLExpression<EClassifier> query = null;<br> | |
<br> | |
try {<br> | |
// create an OCL instance for Ecore<br> | |
OCL<?, EClassifier, ?, ?, ?, ?, ?, ?, ?, Constraint, EClass, EObject> ocl;<br> | |
ocl = OCL.newInstance(EcoreEnvironmentFactory.INSTANCE);<br> | |
<br> | |
// create an OCL helper object<br> | |
OCLHelper<EClassifier, ?, ?, Constraint> helper = ocl.createOCLHelper();<br> | |
<br> | |
// set the OCL context classifier<br> | |
helper.setContext(EXTLibraryPackage.Literals.WRITER);<br> | |
<br> | |
query = helper.createQuery("self.books->collect(b : Book | b.category)->asSet()");<br> | |
<br> | |
// record success<br> | |
valid = true;<br> | |
} catch (ParserException e) {<br> | |
// record failure to parse<br> | |
valid = false;<br> | |
System.err.println(e.getLocalizedMessage());<br> | |
}<br> | |
</code> | |
</p> | |
</div> | |
<p></p> | |
<p>The example above parses an expression that computes the distinct categories | |
of | |
<code class="code">Book</code> s associated with a | |
<code class="code">Writer</code>. The possible | |
reasons why it would fail to parse (in which case a | |
<code class="code">ParserException</code> is thrown) include: | |
</p> | |
<div class="itemizedlist"> | |
<ul class="itemizedlist" type="disc"> | |
<li class="listitem"> | |
<p>syntactical problems: misplaced or missing constructs such as closing</p> | |
</li> | |
</ul> | |
</div> | |
<p> parentheses, variable declarations, type expressions, etc.</p> | |
<div class="itemizedlist"> | |
<ul class="itemizedlist" type="disc"> | |
<li class="listitem"> | |
<p>semantic problems: unknown attributes or operations of the context</p> | |
</li> | |
</ul> | |
</div> | |
<p> type or referenced types, unknown packages, classes, etc.</p> | |
</div> | |
<div class="section" title="Parsing OCL Constraints"> | |
<div class="titlepage"> | |
<div> | |
<div> | |
<h3 class="title"> | |
<a name="ParsingOCLConstraints"></a>Parsing OCL Constraints</h3> | |
</div> | |
</div> | |
</div> | |
<p>OCL is primarily intended for the specification of | |
<span class="emphasis"><em>constraint</em></span> s. Unlike | |
queries, there are a variety of different kinds of constraints used in different | |
places in a model. These include classifier invariants, operation constraints, | |
and attribute derivation constraints. The | |
<code class="code">OCLHelper</code> | |
can parse these for us. | |
</p> | |
<p>Let’s imagine the confusion that arises from a library that has more than | |
one book of the same title (we are not intending to model copies). We will | |
create an invariant constraint for @Book@s stipulating | |
that this is not permitted:</p> | |
<div class="literallayout"> | |
<p> | |
<code class="code">Constraint invariant = null;<br> | |
<br> | |
try {<br> | |
// set the OCL context classifier<br> | |
helper.setContext(EXTLibraryPackage.Literals.LIBRARY);<br> | |
<br> | |
invariant = helper.createInvariant(<br> | |
"Library.allInstances()->forAll(b1, b2 | b1 <> b2 implies b1.title <> b2.title)");<br> | |
} catch (ParserException e) {<br> | |
// record failure to parse<br> | |
System.err.println(e.getLocalizedMessage());<br> | |
}<br> | |
</code> | |
</p> | |
</div> | |
<p></p> | |
<p>Parsing constraints differs from parsing query expressions because they have | |
additional well-formedness rules that the parser checks. For example, an | |
invariant constraint must be boolean-valued, an attribute derivation constraint | |
must conform to the type of the attribute, and such constructs as @pre | |
and | |
<code class="code">oclIsNew()</code> may only be used in operation post-condition constraints. | |
</p> | |
</div> | |
<div class="section" title="Evaluating OCL Expressions and Constraints"> | |
<div class="titlepage"> | |
<div> | |
<div> | |
<h3 class="title"> | |
<a name="EvaluatingOCLExpressionsandConstraints"></a>Evaluating OCL Expressions and Constraints</h3> | |
</div> | |
</div> | |
</div> | |
<p>More interesting than parsing an OCL expression or constraint is evaluating it | |
on some object. The | |
<a class="ulink" href="http://download.eclipse.org/ocl/javadoc/6.4.0/org/eclipse/ocl/Query.html" target="_new"> | |
<code class="code">Query</code> | |
</a> | |
interface provides two methods for evaluating expressions. Queries are | |
constructed by factory methods on the | |
<code class="code">OCL</code> class. | |
</p> | |
<div class="itemizedlist"> | |
<ul class="itemizedlist" type="disc"> | |
<li class="listitem"> | |
<p> | |
<a class="ulink" href="http://download.eclipse.org/ocl/javadoc/6.4.0/org/eclipse/ocl/Query.html#evaluate(org.eclipse.emf.ecore.EObject)" target="_new"> | |
<code class="code">Object evaluate(Object)</code> | |
</a> | |
</p> | |
</li> | |
</ul> | |
</div> | |
<p> evaluates the expression on the specified object, returning the result. | |
The caller is expected to know the result type, which could be a | |
primitive, | |
<code class="code">EObject</code>, or a collection. There | |
are variants of this method for evaluation of the query on multiple | |
objects and on no object at all (for queries that require no "self" | |
context). | |
</p> | |
<div class="itemizedlist"> | |
<ul class="itemizedlist" type="disc"> | |
<li class="listitem"> | |
<p> | |
<a class="ulink" href="http://download.eclipse.org/ocl/javadoc/6.4.0/org/eclipse/ocl/Query.html#check(org.eclipse.emf.ecore.EObject)" target="_new"> | |
<code class="code">boolean evaluate(Object)</code> | |
</a> | |
</p> | |
</li> | |
</ul> | |
</div> | |
<p> This method evaluates a special kind of OCL expression called a | |
<span class="emphasis"><em>constraint</em></span>. Constraints are distinguished from other OCL queries | |
by having a boolean value; thus, they can be used to implement invariant | |
or pre/post-condition constraints. There are variants for checking | |
multiple objects and for selecting/rejecting elements of a list that | |
satisfy the constraint. | |
</p> | |
<p>In order to support the | |
<code class="code">allInstances()</code> operation on OCL types, | |
the | |
<code class="code">OCL</code> API provides the | |
</p> | |
<p> | |
<a class="ulink" href="http://download.eclipse.org/ocl/javadoc/6.4.0/org/eclipse/ocl/OCL.html#setExtentMap(java.util.Map)" target="_new"> | |
<code class="code">setExtentMap(Map<CLS, ? extends Set<? extends E>> extentMap)</code> | |
</a> | |
method. This assigns a mapping of classes (in the Ecore binding, | |
<code class="code">EClass</code> es) to the sets of their instances. By default, | |
the | |
<code class="code">OCL</code> provides a dynamic map that computes the | |
extents on demand from the contents of a | |
<code class="code">Resource</code>. | |
An alternative extent map can be | |
found in | |
<a class="ulink" href="http://download.eclipse.org/ocl/javadoc/6.4.0/org/eclipse/ocl/ecore/opposites/ExtentMap.html" target="_new"> | |
<code class="code">org.eclipse.ocl.ecore.opposites.ExtentMap</code> | |
</a> . | |
We will use a custom extent map in evaluating a query expression that finds | |
books that have the same title as a designated book: | |
</p> | |
<div class="literallayout"> | |
<p> | |
<code class="code">// create an extent map<br> | |
Map<EClass, Set<? extends EObject>> extents = new HashMap<EClass, Set<? extends EObject>>();<br> | |
Set<Book> books = new HashSet<Book>();<br> | |
extents.put(EXTLibraryPackage.Literals.BOOK, books);<br> | |
<br> | |
// tell the OCL environment what our classifier extents are<br> | |
ocl.setExtentMap(extents);<br> | |
<br> | |
Library library = EXTLibraryFactory.eINSTANCE.createLibrary();<br> | |
<br> | |
Book myBook = EXTLibraryFactory.eINSTANCE.createBook();<br> | |
myBook.setTitle("David Copperfield");<br> | |
books.add(myBook);<br> | |
<br> | |
// this book is in our library<br> | |
library.add(myBook);<br> | |
<br> | |
Writer dickens = EXTLibraryFactory.eINSTANCE.createWriter();<br> | |
dickens.setName("Charles Dickens");<br> | |
<br> | |
Book aBook = EXTLibraryFactory.eINSTANCE.createBook();<br> | |
aBook.setTitle("The Pickwick Papers");<br> | |
aBook.setCategory(BookCategory.MYSTERY_LITERAL);<br> | |
books.add(aBook);<br> | |
aBook = EXTLibraryFactory.eINSTANCE.createBook();<br> | |
aBook.setTitle("David Copperfield");<br> | |
aBook.setCategory(BookCategory.BIOGRAPHY_LITERAL); // not actually, of course!<br> | |
books.add(aBook);<br> | |
aBook = EXTLibraryFactory.eINSTANCE.createBook();<br> | |
aBook.setTitle("Nicholas Nickleby");<br> | |
aBook.setCategory(BookCategory.BIOGRAPHY_LITERAL); // not really<br> | |
books.add(aBook);<br> | |
<br> | |
dickens.addAll(books); // Dickens wrote these books<br> | |
library.addAll(books); // and they are all in our library<br> | |
<br> | |
// use the query expression parsed before to create a Query<br> | |
Query<EClassifier, EClass, EObject> eval = ocl.createQuery(query);<br> | |
<br> | |
Collection<?> result = (Collection<?>) eval.evaluate(dickens);<br> | |
System.out.println(result);<br> | |
</code> | |
</p> | |
</div> | |
<p></p> | |
<p>The same | |
<code class="code">Query</code> API is used to check constraints. | |
Using the | |
<code class="code">library</code> and | |
<code class="code">extents</code> map from above and the | |
constraint parsed previously: | |
</p> | |
<div class="literallayout"> | |
<p> | |
<code class="code">eval = ocl.createQuery(constraint);<br> | |
<br> | |
boolean ok = eval.check(library);<br> | |
<br> | |
System.out.println(ok);<br> | |
</code> | |
</p> | |
</div> | |
<p></p> | |
</div> | |
<div class="section" title="Implementing Content Assist"> | |
<div class="titlepage"> | |
<div> | |
<div> | |
<h3 class="title"> | |
<a name="ImplementingContentAssist"></a>Implementing Content Assist</h3> | |
</div> | |
</div> | |
</div> | |
<p>The | |
<code class="code">OCLHelper</code> interface provides an operation that | |
computes content-assist proposals in an abstract form, as | |
<a class="ulink" href="http://download.eclipse.org/ocl/javadoc/6.4.0/org/eclipse/ocl/helper/Choice.html" target="_new"> | |
<code class="code">Choice</code> | |
</a> s. | |
An application’s UI can then convert these to JFace’s | |
<code class="code">ICompletionProposal</code> type. | |
</p> | |
<p>Obtaining completion choices consists of supplying a partial OCL expression | |
(up to the cursor location in the UI editor) to the | |
<a class="ulink" href="http://download.eclipse.org/ocl/javadoc/6.4.0/org/eclipse/ocl/helper/OCLHelper.html#getSyntaxHelp(org.eclipse.ocl.helper.ConstraintKind" target="_new"> | |
<code class="code">OCLHelper::getSyntaxHelp(ConstraintKind, String)</code> | |
</a>, java.lang.String) | |
method. This method requires a | |
<code class="code">ConstraintKind</code> | |
enumeration indicating the type of constraint that is to be parsed (some OCL | |
constructs are restricted in the kinds of constraints in which they may be used). | |
</p> | |
<div class="literallayout"> | |
<p> | |
<code class="code">helper.setContext(EXTLibraryPackage.Literals.BOOK);<br> | |
<br> | |
List<Choice> choices = helper.getSyntaxHelp(<br> | |
ConstraintKind.INVARIANT,<br> | |
"Book.allInstances()->excluding(self).");<br> | |
<br> | |
for (Choice next : choices) {<br> | |
switch (next.getKind()) {<br> | |
case OPERATION:<br> | |
case SIGNAL:<br> | |
// the description is already complete<br> | |
System.out.println(next.getDescription());<br> | |
case PROPERTY:<br> | |
case ENUMERATION_LITERAL:<br> | |
case VARIABLE:<br> | |
System.out.println(next.getName() + " : " + next.getDescription();<br> | |
break;<br> | |
default:<br> | |
System.out.println(next.getName());<br> | |
break;<br> | |
}<br> | |
}<br> | |
</code> | |
</p> | |
</div> | |
<p></p> | |
<p>A sample of the output looks like:</p> | |
<div class="literallayout"> | |
<p> | |
<code class="code">author : Writer<br> | |
title : String<br> | |
oclIsKindOf(typespec : OclType)<br> | |
oclAsType(typespec : OclType) : T<br> | |
...<br> | |
</code> | |
</p> | |
</div> | |
<p></p> | |
<p>The choices also provide the model element that they represent, from which a | |
more sophisticated application can construct appropriate JFace completions, | |
including context information, documentation, etc.</p> | |
</div> | |
<div class="section" title="Working with the AST"> | |
<div class="titlepage"> | |
<div> | |
<div> | |
<h3 class="title"> | |
<a name="WorkingwiththeAST"></a>Working with the AST</h3> | |
</div> | |
</div> | |
</div> | |
<p>The OCL Interpreter models the OCL language using EMF’s Ecore with support for | |
Java-style generic types. The bindings of this generic Abstract Syntax Model | |
for Ecore and for UML substitutes these metamodels' constructs for the generic | |
type parameters, plugging in the definitions of the “classifier”, “operation”, | |
“constraint”, etc. constructs of the OCL vocabulary. These bindings, then, | |
support persistence in or as an adjunct to Ecore and UML models.</p> | |
<p>For processing the abstract syntax tree (AST) parsed from OCL text, the API | |
supplies a | |
<a class="ulink" href="http://download.eclipse.org/ocl/javadoc/6.4.0/org/eclipse/ocl/utilities/Visitor.html" target="_new"> | |
<code class="code">Visitor</code> | |
</a> | |
interface. By implementing this interface (or extending the | |
<a class="ulink" href="http://download.eclipse.org/ocl/javadoc/6.4.0/org/eclipse/ocl/utilities/AbstractVisitor.html" target="_new"> | |
<code class="code">AbstractVisitor</code> | |
</a> | |
class, which is recommended), we can walk the AST of an OCL expression to | |
transform it in some way. | |
This is exactly what the interpreter, itself, does to evaluate an | |
expression: it just walks the expression using an evaluation visitor. For | |
example, we can count the number times that a specific attribute is | |
referenced in an expression: | |
</p> | |
<div class="literallayout"> | |
<p> | |
<code class="code">helper.setContext(EXTLibraryPackage.Literals.BOOK);<br> | |
<br> | |
OCLExpression<EClassifier> query = helper.parseQuery(<br> | |
"Book.allInstances()->select(b : Book | b <> self and b.title = self.title)");<br> | |
<br> | |
AttributeCounter visitor = new AttributeCounter(<br> | |
EXTLibraryPackage.Literals.BOOK__TITLE);<br> | |
<br> | |
System.out.println(<br> | |
"Number of accesses to the 'Book::title' attribute: " + query.accept(visitor));<br> | |
</code> | |
</p> | |
</div> | |
<p></p> | |
<p>where the visitor is defined thus:</p> | |
<div class="literallayout"> | |
<p> | |
<code class="code">class AttributeCounter extends AbstractVisitor<Integer,<br> | |
EClassifier, EOperation, EStructuralFeature, EEnumLiteral,<br> | |
EParameter, EObject, EObject, EObject, Constraint> {<br> | |
private final EAttribute attribute;<br> | |
<br> | |
AttributeCounter(EAttribute attribute) {<br> | |
super(0); // initialize the result of the AST visitiation to zero<br> | |
this.attribute = attribute;<br> | |
}<br> | |
<br> | |
protected Integer handlePropertyCallExp(PropertyCallExp<EClassifier, EStructuralFeature> callExp,<br> | |
Integer sourceResult, List<Integer> sourceResults) {<br> | |
if (callExp.getReferredProperty() == attribute) {<br> | |
// count one<br> | |
result++;<br> | |
}<br> | |
<br> | |
return result;<br> | |
}<br> | |
}<br> | |
</code> | |
</p> | |
</div> | |
<p></p> | |
</div> | |
<div class="section" title="Serialization"> | |
<div class="titlepage"> | |
<div> | |
<div> | |
<h3 class="title"> | |
<a name="Serialization"></a>Serialization</h3> | |
</div> | |
</div> | |
</div> | |
<p>Because the OCL expression AST is a graph of EMF objects, we can serialize it | |
to an XMI file and deserialize it again later. To save our example expression, | |
we start over by initializing our | |
<code class="code">OCL</code> instance with | |
a resource in which it will persist the environment and in which we will | |
persist the parsed expression. The key is in the persistence of the | |
environment: OCL defines a variety of classes on the fly by template | |
instantiation. These include collection types, tuple types, and message types. | |
Other elements needing to be persisted are additional operations and attributes | |
that may be defined in the local environment. | |
</p> | |
<div class="literallayout"> | |
<p> | |
<code class="code">// create a resource in which to store our parsed OCL expressions and constraints<br> | |
Resource res = resourceSet.createResource(<br> | |
URI.createPlatformResourceURI("/MyProject/myOcl.xmi", true);<br> | |
<br> | |
// initialize a new OCL environment, persisted in this resource<br> | |
ocl = OCL.newInstance(EcoreEnvironmentFactory.INSTANCE, res);<br> | |
<br> | |
// for the new OCL environment, create a new helper<br> | |
helper = OCL.createOCLHelper();<br> | |
<br> | |
helper.setContext(EXTLibraryPackage.Literals.BOOK);<br> | |
<br> | |
// try a very simple expression<br> | |
OCLExpression<EClassifier> query = helper.createQuery("self.title");<br> | |
<br> | |
// store our query in this resource. All of its necessary environment has<br> | |
// already been stored, so we insert the query as the first resource root<br> | |
res.getContents().add(0, query);<br> | |
<br> | |
res.save(Collections.emptyMap());<br> | |
res.unload();<br> | |
</code> | |
</p> | |
</div> | |
<p></p> | |
<p>To load a saved OCL expression is just as easy:</p> | |
<div class="literallayout"> | |
<p> | |
<code class="code">Resource res = resourceSet.getResource(<br> | |
URI.createPlatformResourceURI("/MyProject/myOcl.xmi", true),<br> | |
true;<br> | |
<br> | |
@SuppressWarnings("unchecked")<br> | |
OCLExpression<EClassifier> query = (OCLExpression<EClassifier>) res.getContents().get(0);<br> | |
<br> | |
System.out.println(ocl.evaluate(myBook, query));<br> | |
</code> | |
</p> | |
</div> | |
<p></p> | |
<p>In the snippet above, we used the | |
<code class="code">OCL</code>'s convenience | |
method for a one-shot evaluation of a query. Looking at the contents of the | |
XMI document that we saved, we see that the | |
<code class="code">self</code> | |
variable declaration is not owned by the query expression, but is, rather, | |
free-standing. The | |
<code class="code">ExpressionInOCL</code> metaclass solves | |
this problem by providing properties that contain context variable declarations, | |
including | |
<code class="code">self</code> and (in the context of operations) | |
operation parameters. | |
</p> | |
<div class="literallayout"> | |
<p> | |
<code class="code"><?xml version="1.0" encoding="ASCII"?><br> | |
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:ocl.ecore="http://www.eclipse.org/ocl/1.1.0/Ecore"><br> | |
<ocl.ecore:PropertyCallExp xmi:id="_897fVPfmEduCQ48h829a5g"><br> | |
<eType xsi:type="ocl.ecore:PrimitiveType" href="http://www.eclipse.org/ocl/1.1.0/oclstdlib.ecore#/0/String"/><br> | |
<source xsi:type="ocl.ecore:VariableExp" xmi:id="_897fVvfmEduCQ48h829a5g" name="self" referredVariable="_897fUvfmEduCQ48h829a5g"><br> | |
<eType xsi:type="ecore:EClass" href="http://www.org.eclipse/ocl/examples/library/extlibrary.ecore/1.0.0#//Book"/><br> | |
</source><br> | |
<referredProperty xsi:type="ecore:EAttribute" href="http://www.org.eclipse/ocl/examples/library/extlibrary.ecore/1.0.0#//Book/title"/><br> | |
</ocl.ecore:PropertyCallExp><br> | |
<ocl.ecore:Variable xmi:id="_897fUvfmEduCQ48h829a5g" name="self"><br> | |
<eType xsi:type="ecore:EClass" href="http://www.org.eclipse/ocl/examples/library/extlibrary.ecore/1.0.0#//Book"/><br> | |
</ocl.ecore:Variable><br> | |
</xmi:XMI><br> | |
</code> | |
</p> | |
</div> | |
<p></p> | |
</div> | |
<div class="section" title="Summary"> | |
<div class="titlepage"> | |
<div> | |
<div> | |
<h3 class="title"> | |
<a name="Summary3"></a>Summary</h3> | |
</div> | |
</div> | |
</div> | |
<p>To illustrate how to work with the OCL API, we</p> | |
<div class="itemizedlist"> | |
<ul class="itemizedlist" type="disc"> | |
<li class="listitem"> | |
<p>Parsed and validated OCL expressions and constraints.</p> | |
</li> | |
<li class="listitem"> | |
<p>Evaluated OCL query expressions and constraints.</p> | |
</li> | |
<li class="listitem"> | |
<p>Obtained content-assist suggestions for the completion of OCL expressions.</p> | |
</li> | |
<li class="listitem"> | |
<p>Transformed an OCL expression AST using the | |
<span class="emphasis"><em>Visitor</em></span> pattern. | |
</p> | |
</li> | |
<li class="listitem"> | |
<p>Saved and loaded OCL expressions to/from XMI resources.</p> | |
</li> | |
</ul> | |
</div> | |
</div> | |
</div> | |
</body> | |
</html> |