如何处理 emf M2M 中的复杂类型

how to handle complexed type in emf M2M

我是 EMF M2M 的初学者。当目标模型包含复杂类型时,我在使用 ATL 时遇到问题。这是一个小例子来展示它。假设我从Families.ecore(与ATL网站示例Faimilies2Persons相同)的模型转移到Graph.ecore(关键部分如下所示)。我想创建一个图表,其中每个家庭成员都是一个节点,如果他们是男性或女性,则连接两个节点。然后我从这个模板开始,如下所示。结果每个成员都是一个节点,但同时我得到多个图,每个图只有一个节点。所以任何人都可以给我一些帮助如何将所有节点放入一个图中?原则上,我认为当 ATL 处理具有层次结构复杂类型的模型时,这是一个非常普遍的问题。非常感谢!

module families2graph;
create OUT : graph from IN : Families;

entrypoint rule myrule() {
 to
  t: graph!Graph (
    name <-  'mygraph',
    type <- #Directed

  )
}
rule Member2Female {
 from
  s : Families!Member 
 to
  t1 : graph!Graph (
   nodes <- t2 
  ),
  t2 : graph!Node (
   name <- s.firstName 
  )
}

<eClassifiers xsi:type="ecore:EClass" name="Graph">
  <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
    <details key="name" value="Graph" />
    <details key="kind" value="elementOnly" />
  </eAnnotations>
  <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
      <details key="kind" value="element" />
      <details key="name" value="name" />
    </eAnnotations>
  </eStructuralFeatures>
  <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" lowerBound="1" eType="#//EdgeDirection" unsettable="true">
    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
      <details key="kind" value="element" />
      <details key="name" value="type" />
    </eAnnotations>
  </eStructuralFeatures>
  <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" eType="#//Node" containment="true" resolveProxies="false">
    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
      <details key="kind" value="element" />
      <details key="name" value="nodes" />
    </eAnnotations>
  </eStructuralFeatures>
  <eStructuralFeatures xsi:type="ecore:EReference" name="edges" upperBound="-1" eType="#//Edge" containment="true" resolveProxies="false">
    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
      <details key="kind" value="element" />
      <details key="name" value="edges" />
    </eAnnotations>
  </eStructuralFeatures>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Node">
  <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
    <details key="name" value="Node" />
    <details key="kind" value="elementOnly" />
  </eAnnotations>
  <eStructuralFeatures xsi:type="ecore:EReference" name="connectedEdges" upperBound="-1" eType="#//Edge" resolveProxies="false">
    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
      <details key="kind" value="element" />
      <details key="name" value="ConnectedEdges" />
    </eAnnotations>
  </eStructuralFeatures>
  <eStructuralFeatures xsi:type="ecore:EReference" name="properties" upperBound="-1" eType="#//Property" containment="true" resolveProxies="false">
    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
      <details key="kind" value="element" />
      <details key="name" value="properties" />
    </eAnnotations>
  </eStructuralFeatures>
  <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
      <details key="kind" value="attribute" />
      <details key="name" value="name" />
    </eAnnotations>
  </eStructuralFeatures>
</eClassifiers>

您的规则 Member2Female 指定从 Member 中创建两个元素:GraphNode。您必须将 nodes <-... 部分放入创建 "main" Graph 元素的 myrule() 入口点。你可以试试这个:

module families2graph;
create OUT : graph from IN : Families;

entrypoint rule myrule() {
    to
        t: graph!Graph (
             name <-  'mygraph',
             type <- #Directed,
             nodes <- Families!Member.allInstances()->collect(e | thisModule.Member2Female(e))
        )
}

unique lazy rule Member2Female {
    from
        s : Families!Member 
    to
        t : graph!Node (
            name <- s.firstName 
        )
}

注释行表示 nodes 引用将拥有从 Families 模型的所有 Member 实例生成的元素。

如果您想了解更多详情,可以尝试:https://wiki.eclipse.org/ATL/User_Guide_-_The_ATL_Language 并查找 Journal2Book 规则定义和解释。