EMF-如何以编程方式从模型中删除实例

时间:2014-03-28 02:43:35

标签: eclipse-emf emf eclipse-emf-ecore ecore

我创建了名为WFG.ecore的元模型。

使用ATL,我设法在WFG模型中转换bpmn2文件。 ATL转换赋予对象WorkFlow,即WFG中所有其他对象的容器。

现在我想用Java编程修改对象WorkFlow,但我不能。

如何从容器中删除对象实例,以及从所有实例中删除?

下面是一个实例

的例子
            gateways
           +--------->+----------+
           |          |Gateway_1 |
           ♦          +----------+
+-----------+              ^
|WorkFlow_1 |              | nextGateway 0..1
+-----------+              |
           ♦           +---------+
           |           | Node_1  |
           +---------->+---------+
           nodes

我想删除Gateway_1实例,以便WorkFlow_1中不再包含该实例,以及Node_1.getNextGateway->null。我试着这样做 WorkFlow_1.getGateways().remove(Gateway_1)但不起作用

2 个答案:

答案 0 :(得分:1)

天真的答案是使用EcoreUtil.delete()Delete命令。这两个都从其容器中删除EObject并删除(即清空)任何交叉引用。但是,一般情况下,由于以下原因,您不希望这样做:

  1. 儿童参考。虽然EcoreUtil.delete(Gateway_1)会从其容器和Gateway_1引用中删除Node_1,但它不会删除对Gateway_1 的子项的任何交叉引用即使他们也将从他们的容器中删除 。因此,您最终可能会悬挂对不存在的Gateway_1子项的对象的引用。

  2. 性能。没有可靠的方法可以有效地找到交叉引用。这意味着将检查模型中的每个EObject以查看它是否具有Gateway_1的交叉引用,以便可以删除交叉引用。这使EcoreUtil.delete()成为 O(n)操作,其中 n 是模型中EObject的数量。

  3. 最佳解决方案是双向引用和参考映射的某种组合。 Gateway_1应该知道谁在交叉引用它,或者该信息应该可以在其他地方访问。这样,您就可以高效,完整地显式删除对Gateway_1的所有引用。

    这个答案紧跟this blog post, EMF Dos and Don'ts #11, by Maximilian Koegel and Jonas Helming

    顺便说一下,EcoreUtil.remove()不会删除交叉引用,它只是从容器中删除了EObject。

答案 1 :(得分:-1)

DeleteCommand.create(editingDomain, Collections.singleton(Gateway_1));
editingDomain.getCommandStack().execute(command);

对于Node_1:

Node_1.setNextGateway(null);