不知道有没有可能,直接使用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()返回ETreeIteratorQVT 引擎未转换的 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无法访问,您仍然可以强制转换为EObjectusing 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 提出的解决方案比我在这里提出的解决方案更优雅,应该被首选。