I don't know if it is possible, using directly coveredBy
to get an ordered collection. As coveredBy
is unordered, if you access it directly by the feature, you will have an unpredictible order and if you try to access it using the eGet(...)
stuff, the same result will occur.
However, if I understood correctly, there is a "trick" that could work.
It relies on the assumption that each OccurrenceSpecification
instance you need is held by the same Interaction
that contains the Lifeline
and uses the way EMF stores contained elements. Actually, each contained element is always kind of 'ordered' relatively to its parent (and for each collection so EMF can find elements back when XMI references are expressed using the element position in collections). So, the idea would be to access all the elements contained by the Interaction
that owns the lifeline and filter the ones that are contained in coveredBy
.
Expression with Acceleo
This is easy to write in MTL/Acceleo. In know you don't use it, but it illustrates what the expression does:
# In Acceleo:
# 'self' is the lifeline instance
self.interaction.eAllContents(OccurrenceSpecification)->select(e | self.coveredBy->includes(e))->asOrderedSet()
with self.interaction
we retrieve the Interaction
, then we get all the contained elements with eAllContents(...)
and we filter the ones that are in the self.coveredBy
collection.
But it is way less intuitive in QVT as eAllContents(...)
does not exist. Instead you have to gain access to eContents()
which is defined on EObject
and returns an EList
which is transtyped to a Sequence
(in QVT,eAllContents()
returns a ETreeIterator
which is not transtyped by the QVT engine).
So, how to gain access to eContents()
in the helper? There is two solutions:
Solution 1: Using the emf.tools
library
The emf.tools
library give you the ability to use asEObject()
which casts your object in a pure EObject
and give you more methods to access to (as eClass()
for example...etc).
import emf.tools; -- we import the EMF tools library
modeltype UML ...; -- all your metamodel imports and stuffs
...
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.asEObject().eContents()[OccurrenceSpecification]->select(e | self.coveredBy->includes(e))->asOrderedSet();
}
Solution 2: Using oclAstype(...)
If for some reason emf.tools
cannot be accessed, you can still cast to an EObject
using oclAsType(...)
.
modeltype UML ...; -- all your metamodel imports and stuffs
modeltype ECORE "strict" uses ecore('http://www.eclipse.org/emf/2002/Ecore'); -- you also register the Ecore metamodel
...
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.oclAsType(EObject).eContents()[OccurrenceSpecification]->select(e | self.coveredBy->includes(e))->asOrderedSet();
}
Limitation
Ok, let's be honest here, this solution seems to work on the quick tests I performed, but I'm not a 100% sure that you will have all the elements you want as this code relies on the strong assumption that every OccurrenceSpecification
you need are in the same Interaction
as the Liteline
instance. If you are sure that all the coveredBy
elements you need are in the Interaction
(I think they should be), then, that's not the sexiest solution, but it should do the work.
EDIT>
The solution proposed by hielsnoppe is more eleguant than the one I presented here and should be prefered.