Home » Modeling » OCL » Evaluation of allInstances and self usage
|
Re: Evaluation of allInstances and self usage [message #53653 is a reply to message #53626] |
Mon, 07 April 2008 16:21 |
Eclipse User |
|
|
|
Originally posted by: cdamus.ca.ibm.com
Hi, Michael,
See some replies in-line, below.
HTH,
Christian
Michael Soden wrote:
> Hi folks,
>
> I came across some questions regarding the 'allInstances' implementation.
>
> First of all I'm wondering why I have to specify a 'self' object for
> evaluation of an 'allInstances' query. Suppose a query in the EcoreEval
> env over a metamodel having class 'A' like:
>
> [...]
> OCLExpression oclExpr = helper.createQuery("A.allInstances()");
> query.evaluate();
Hmm ... I would expect it to return an empty set, not null. That sounds
bad.
Anyway, the "self" context is required in order to find the extent of your A
class, but only when using the default implementation of the extent-map.
The EvaluationEnvironment relies on an "extent-map" that maps Classes to the
sets of their instances. The default implementation of this is the
LazyExtentMap class, but you can supply your own if you need a different
algorithm. The LazyExtentMap will compute the extent of a class by finding
all of its instances in the Resource containing the context object. This
is why the "self" context object is required, in order to find that
resource context.
Other implementations that I have seen also require a context object, for
example to find a ResourceSet in which all instances of the class are
found. Yet another implementation doesn't require any context element,
because it uses an AspectJ aspect to track absolutely all instances of
EClasses; see the initial contribution to the MDT OCLTools component for
that one.
> it will return 'null', since the implementation cannot figure out in
> what extent (i.e. resources) my objects live. If I provide an apropriate
> 'self', everything works fine. However, what shall I do if a query uses
> multiple different meta-classes? For example let's take the following
> query (underlying metamodel has simply two classes, not inheriting each
> other, both having an EString attribute 'name'):
>
> A.allInstances()->select( a | B.allInstances()->exists( b | b.name =
> a.name ) )
Multiple different metaclasses are all handled similarly. The LazyExtentMap
will find all instances of A and of B in the Resource containing
your "self" context element.
> Shall I provide an 'A' instance or a 'B' for evaluation? What happens if
> a query uses already 'self' bound to a different type (in my example
> let's say 'B'):
>
> AB::A.allInstances()->select(a : A | a.name.=(self.name))
The context element needs not have any particular relationship to the class
whose extent you are querying. It only provides the Resource in which to
search for instances of the named metaclasses.
> Thanks in advance for bringing light into the dark,
> Michael
>
> PS: I attached my sample project if somebody wants to take a closer look
|
|
|
Re: Evaluation of allInstances and self usage [message #53678 is a reply to message #53653] |
Mon, 07 April 2008 17:38 |
Michael Soden Messages: 27 Registered: July 2009 |
Junior Member |
|
|
Hi Christian,
thanks for your quick answer. I successfully tried to supply my own
extent map and it worked. If anybody is interested in a code snippet
(see below).
Would be nice if there is a way to reuse the LazyExtentMap
implementation in a way that is independent of a specific object (passed
during construction). Actually, it seems only to be used to determine
the extent (either used directly as root or extent by looking up the
objects resource). What about having a second constructor with a
resource (or root object collection) directly?
Many thanks again,
Michael
--- snipp ---
Map<EClass, Set<EObject>> extent = new HashMap<EClass,Set<EObject>>();
Iterator<EObject> iterator = model.getAllContents();
while (iterator.hasNext()) {
EObject element = iterator.next();
Set<EObject> set = extent.get(element.eClass());
if (set == null) {
set = new HashSet<EObject>();
extent.put(element.eClass(), set);
}
set.add(element);
}
OCL ocl = OCL.newInstance(EcoreEnvironmentFactory.INSTANCE);
final OCLHelper<EClassifier, ?, ?, ?> helper = ocl.createOCLHelper();
ocl.setExtentMap(extent);
---
Christian W. Damus schrieb:
> Hi, Michael,
>
> See some replies in-line, below.
>
> HTH,
>
> Christian
>
>
> Michael Soden wrote:
>
>> Hi folks,
>>
>> I came across some questions regarding the 'allInstances' implementation.
>>
>> First of all I'm wondering why I have to specify a 'self' object for
>> evaluation of an 'allInstances' query. Suppose a query in the EcoreEval
>> env over a metamodel having class 'A' like:
>>
>> [...]
>> OCLExpression oclExpr = helper.createQuery("A.allInstances()");
>> query.evaluate();
>
> Hmm ... I would expect it to return an empty set, not null. That sounds
> bad.
>
> Anyway, the "self" context is required in order to find the extent of your A
> class, but only when using the default implementation of the extent-map.
>
> The EvaluationEnvironment relies on an "extent-map" that maps Classes to the
> sets of their instances. The default implementation of this is the
> LazyExtentMap class, but you can supply your own if you need a different
> algorithm. The LazyExtentMap will compute the extent of a class by finding
> all of its instances in the Resource containing the context object. This
> is why the "self" context object is required, in order to find that
> resource context.
>
> Other implementations that I have seen also require a context object, for
> example to find a ResourceSet in which all instances of the class are
> found. Yet another implementation doesn't require any context element,
> because it uses an AspectJ aspect to track absolutely all instances of
> EClasses; see the initial contribution to the MDT OCLTools component for
> that one.
>
>
>> it will return 'null', since the implementation cannot figure out in
>> what extent (i.e. resources) my objects live. If I provide an apropriate
>> 'self', everything works fine. However, what shall I do if a query uses
>> multiple different meta-classes? For example let's take the following
>> query (underlying metamodel has simply two classes, not inheriting each
>> other, both having an EString attribute 'name'):
>>
>> A.allInstances()->select( a | B.allInstances()->exists( b | b.name =
>> a.name ) )
>
> Multiple different metaclasses are all handled similarly. The LazyExtentMap
> will find all instances of A and of B in the Resource containing
> your "self" context element.
>
>
>> Shall I provide an 'A' instance or a 'B' for evaluation? What happens if
>> a query uses already 'self' bound to a different type (in my example
>> let's say 'B'):
>>
>> AB::A.allInstances()->select(a : A | a.name.=(self.name))
>
> The context element needs not have any particular relationship to the class
> whose extent you are querying. It only provides the Resource in which to
> search for instances of the named metaclasses.
>
>
>> Thanks in advance for bringing light into the dark,
>> Michael
>>
>> PS: I attached my sample project if somebody wants to take a closer look
>
|
|
|
Re: Evaluation of allInstances and self usage [message #53703 is a reply to message #53678] |
Mon, 07 April 2008 19:38 |
Eclipse User |
|
|
|
Originally posted by: cdamus.ca.ibm.com
Hi, Michael,
I'm glad you got that working.
Besides your idea of supplying a Resource to the LazyExtentMap, I've often
though that it might be beneficial to (optionally) take the entire
ResourceSet as the extent. After all, in some respects, a ResourceSet
comprising a set of interconnected trees really is the "model." Moreover,
any given OCL instance already knows its ResourceSet context at the very
least because the registration of (meta-)models is done at this level.
Any ideas that you have for improvement are welcome as enhancement requests
in the Eclipse bugzilla. Even more welcome if they come with patches! :-)
Cheers,
Christian
Michael Soden wrote:
> Hi Christian,
>
> thanks for your quick answer. I successfully tried to supply my own
> extent map and it worked. If anybody is interested in a code snippet
> (see below).
>
> Would be nice if there is a way to reuse the LazyExtentMap
> implementation in a way that is independent of a specific object (passed
> during construction). Actually, it seems only to be used to determine
> the extent (either used directly as root or extent by looking up the
> objects resource). What about having a second constructor with a
> resource (or root object collection) directly?
>
> Many thanks again,
> Michael
-----8<-----
|
|
|
Goto Forum:
Current Time: Wed Jan 15 08:57:26 GMT 2025
Powered by FUDForum. Page generated in 0.02958 seconds
|