不知道有没有可能,直接使用coveredBy
获取有序集合。就像coveredBy
无序一样,如果您直接通过功能访问它,您将有一个不可预测的顺序,如果您尝试使用这些eGet(...)
东西访问它,则会出现相同的结果。
但是,如果我理解正确,有一个“技巧”可以奏效。它依赖于假设OccurrenceSpecification
您需要的每个实例都由Interaction
包含Lifeline
和使用 EMF 存储包含元素的方式的同一实例持有。实际上,每个包含的元素总是相对于其父元素是“有序的”(对于每个集合,EMF 可以在 XMI 引用使用集合中的元素位置表示时找到元素)。因此,我们的想法是访问Interaction
拥有生命线的 包含的所有元素并过滤包含在coveredBy
.
用 Acceleo 表达
这很容易用 MTL/Acceleo 编写。知道你不使用它,但它说明了表达式的作用:
# In Acceleo:
# 'self' is the lifeline instance
self.interaction.eAllContents(OccurrenceSpecification)->select(e | self.coveredBy->includes(e))->asOrderedSet()
随着self.interaction
我们检索Interaction
,然后我们得到所有包含的元素eAllContents(...)
并过滤self.coveredBy
集合中的元素。
但它在 QVT 中eAllContents(...)
不那么直观,因为它不存在。相反,您必须访问eContents()
which is defined onEObject
并返回EList
转换为 a 的 a Sequence
(在 QVT 中,eAllContents()
返回ETreeIterator
QVT 引擎未转换的 a)。
那么,如何eContents()
在助手中获取访问权限呢?有两种解决方案:
解决方案 1:使用emf.tools
库
该emf.tools
库使您能够使用asEObject()
将对象转换为纯对象的能力,EObject
并为您提供更多访问方法(eClass()
例如...等)。
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();
}
解决方案 2:使用oclAstype(...)
如果由于某种原因emf.tools
无法访问,您仍然可以强制转换为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();
}
局限性
好的,老实说,这个解决方案似乎适用于我执行的快速测试,但我不能 100% 确定你会拥有你想要的所有元素,因为这段代码依赖于OccurrenceSpecification
你需要的每个元素的强烈假设Interaction
与Liteline
实例相同。如果您确定coveredBy
您需要的所有元素都在Interaction
(我认为它们应该是)中,那么这不是最性感的解决方案,但它应该可以工作。
编辑>
hielsnoppe 提出的解决方案比我在这里提出的解决方案更优雅,应该被首选。