我创建了名为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)
但不起作用
答案 0 :(得分:1)
天真的答案是使用EcoreUtil.delete()
或Delete
命令。这两个都从其容器中删除EObject
并删除(即清空)任何交叉引用。但是,一般情况下,由于以下原因,您不希望这样做:
儿童参考。虽然EcoreUtil.delete(Gateway_1)
会从其容器和Gateway_1
引用中删除Node_1
,但它不会删除对Gateway_1
的子项的任何交叉引用即使他们也将从他们的容器中删除 。因此,您最终可能会悬挂对不存在的Gateway_1
子项的对象的引用。
性能。没有可靠的方法可以有效地找到交叉引用。这意味着将检查模型中的每个EObject以查看它是否具有Gateway_1
的交叉引用,以便可以删除交叉引用。这使EcoreUtil.delete()
成为 O(n)操作,其中 n 是模型中EObject的数量。
最佳解决方案是双向引用和参考映射的某种组合。 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);